mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-10 10:08:18 +00:00
Merge #3077
3077: UI Elements r=def- a=Jupeyy Build will fail bcs of clang-format, i'll update this comment to explain. Co-authored-by: Jupeyy <jupjopjap@gmail.com>
This commit is contained in:
commit
b0803b26e0
|
@ -1098,7 +1098,7 @@ public:
|
|||
pCursor->m_Y = DrawY;
|
||||
}
|
||||
|
||||
virtual int CreateTextContainer(CTextCursor *pCursor, const char *pText)
|
||||
virtual int CreateTextContainer(CTextCursor *pCursor, const char *pText, int Length = -1)
|
||||
{
|
||||
CFont *pFont = pCursor->m_pFont;
|
||||
|
||||
|
@ -1152,7 +1152,7 @@ public:
|
|||
|
||||
TextContainer.m_FontSize = pSizeData->m_FontSize;
|
||||
|
||||
AppendTextContainer(pCursor, ContainerIndex, pText);
|
||||
AppendTextContainer(pCursor, ContainerIndex, pText, Length);
|
||||
|
||||
if(TextContainer.m_StringInfo.m_CharacterQuads.size() == 0)
|
||||
{
|
||||
|
@ -1189,7 +1189,7 @@ public:
|
|||
return ContainerIndex;
|
||||
}
|
||||
|
||||
virtual void AppendTextContainer(CTextCursor *pCursor, int TextContainerIndex, const char *pText)
|
||||
virtual void AppendTextContainer(CTextCursor *pCursor, int TextContainerIndex, const char *pText, int Length = -1)
|
||||
{
|
||||
STextContainer &TextContainer = GetTextContainer(TextContainerIndex);
|
||||
|
||||
|
@ -1226,7 +1226,8 @@ public:
|
|||
pSizeData = TextContainer.m_pFont->GetFontSize(TextContainer.m_FontSize);
|
||||
|
||||
// string length
|
||||
int Length = str_length(pText);
|
||||
if(Length < 0)
|
||||
Length = str_length(pText);
|
||||
|
||||
float Scale = 1.0f / pSizeData->m_FontSize;
|
||||
|
||||
|
@ -1455,19 +1456,19 @@ public:
|
|||
}
|
||||
|
||||
// just deletes and creates text container
|
||||
virtual void RecreateTextContainer(CTextCursor *pCursor, int TextContainerIndex, const char *pText)
|
||||
virtual void RecreateTextContainer(CTextCursor *pCursor, int TextContainerIndex, const char *pText, int Length = -1)
|
||||
{
|
||||
DeleteTextContainer(TextContainerIndex);
|
||||
CreateTextContainer(pCursor, pText);
|
||||
CreateTextContainer(pCursor, pText, Length);
|
||||
}
|
||||
|
||||
virtual void RecreateTextContainerSoft(CTextCursor *pCursor, int TextContainerIndex, const char *pText)
|
||||
virtual void RecreateTextContainerSoft(CTextCursor *pCursor, int TextContainerIndex, const char *pText, int Length = -1)
|
||||
{
|
||||
STextContainer &TextContainer = GetTextContainer(TextContainerIndex);
|
||||
TextContainer.m_StringInfo.m_CharacterQuads.clear();
|
||||
TextContainer.m_StringInfo.m_QuadNum = 0;
|
||||
// the text buffer gets then recreated by the appended quads
|
||||
AppendTextContainer(pCursor, TextContainerIndex, pText);
|
||||
AppendTextContainer(pCursor, TextContainerIndex, pText, Length);
|
||||
}
|
||||
|
||||
virtual void SetTextContainerSelection(int TextContainerIndex, const char *pText, int CursorPos, int SelectionStart, int SelectionEnd)
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
#include <engine/map.h>
|
||||
#include <engine/shared/protocol.h>
|
||||
#include <game/client/ui.h>
|
||||
|
||||
#include "kernel.h"
|
||||
|
||||
|
@ -61,6 +62,8 @@ public:
|
|||
char m_aAddress[NETADDR_MAXSTRSIZE];
|
||||
CClient m_aClients[MAX_CLIENTS];
|
||||
mutable int m_NumFilteredPlayers;
|
||||
|
||||
mutable CUIElement *m_pUIElement;
|
||||
};
|
||||
|
||||
bool IsVanilla(const CServerInfo *pInfo);
|
||||
|
|
|
@ -63,6 +63,10 @@ struct STextRenderColor
|
|||
{
|
||||
Set(r, g, b, a);
|
||||
}
|
||||
STextRenderColor(const ColorRGBA &TextColorRGBA)
|
||||
{
|
||||
Set(TextColorRGBA.r, TextColorRGBA.g, TextColorRGBA.b, TextColorRGBA.a);
|
||||
}
|
||||
|
||||
void Set(float r, float g, float b, float a)
|
||||
{
|
||||
|
@ -92,13 +96,16 @@ public:
|
|||
|
||||
virtual void SetRenderFlags(unsigned int Flags) = 0;
|
||||
|
||||
ColorRGBA DefaultTextColor() { return ColorRGBA(1, 1, 1, 1); }
|
||||
ColorRGBA DefaultTextOutlineColor() { return ColorRGBA(0, 0, 0, 0.3f); }
|
||||
|
||||
//
|
||||
virtual void TextEx(CTextCursor *pCursor, const char *pText, int Length) = 0;
|
||||
virtual int CreateTextContainer(CTextCursor *pCursor, const char *pText) = 0;
|
||||
virtual void AppendTextContainer(CTextCursor *pCursor, int TextContainerIndex, const char *pText) = 0;
|
||||
virtual int CreateTextContainer(CTextCursor *pCursor, const char *pText, int Length = -1) = 0;
|
||||
virtual void AppendTextContainer(CTextCursor *pCursor, int TextContainerIndex, const char *pText, int Length = -1) = 0;
|
||||
// just deletes and creates text container
|
||||
virtual void RecreateTextContainer(CTextCursor *pCursor, int TextContainerIndex, const char *pText) = 0;
|
||||
virtual void RecreateTextContainerSoft(CTextCursor *pCursor, int TextContainerIndex, const char *pText) = 0;
|
||||
virtual void RecreateTextContainer(CTextCursor *pCursor, int TextContainerIndex, const char *pText, int Length = -1) = 0;
|
||||
virtual void RecreateTextContainerSoft(CTextCursor *pCursor, int TextContainerIndex, const char *pText, int Length = -1) = 0;
|
||||
virtual void SetTextContainerSelection(int TextContainerIndex, const char *pText, int CursorPos, int SelectionStart, int SelectionEnd) = 0;
|
||||
virtual void DeleteTextContainer(int TextContainerIndex) = 0;
|
||||
|
||||
|
@ -113,6 +120,7 @@ public:
|
|||
virtual void TextColor(float r, float g, float b, float a) = 0;
|
||||
virtual void TextColor(ColorRGBA rgb) = 0;
|
||||
virtual void TextOutlineColor(float r, float g, float b, float a) = 0;
|
||||
virtual void TextOutlineColor(ColorRGBA rgb) = 0;
|
||||
virtual void Text(void *pFontSetV, float x, float y, float Size, const char *pText, float LineWidth) = 0;
|
||||
virtual float TextWidth(void *pFontSetV, float Size, const char *pText, int StrLength, float LineWidth, float *pAlignedHeight = NULL, float *pMaxCharacterHeightInLine = NULL) = 0;
|
||||
virtual int TextLineCount(void *pFontSetV, float Size, const char *pText, float LineWidth) = 0;
|
||||
|
|
|
@ -99,10 +99,10 @@ CMenus::CMenus()
|
|||
float CMenus::ButtonColorMul(const void *pID)
|
||||
{
|
||||
if(UI()->ActiveItem() == pID)
|
||||
return 0.5f;
|
||||
return ButtonColorMulActive();
|
||||
else if(UI()->HotItem() == pID)
|
||||
return 1.5f;
|
||||
return 1;
|
||||
return ButtonColorMulHot();
|
||||
return ButtonColorMulDefault();
|
||||
}
|
||||
|
||||
int CMenus::DoButton_Icon(int ImageId, int SpriteId, const CUIRect *pRect)
|
||||
|
@ -1088,6 +1088,9 @@ void CMenus::OnInit()
|
|||
if(g_Config.m_ClSkipStartMenu)
|
||||
m_ShowStart = false;
|
||||
|
||||
m_RefreshButton.Init(UI());
|
||||
m_ConnectButton.Init(UI());
|
||||
|
||||
Console()->Chain("add_favorite", ConchainServerbrowserUpdate, this);
|
||||
Console()->Chain("remove_favorite", ConchainServerbrowserUpdate, this);
|
||||
Console()->Chain("add_friend", ConchainFriendlistUpdate, this);
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include <engine/friends.h>
|
||||
#include <engine/shared/config.h>
|
||||
#include <engine/shared/linereader.h>
|
||||
#include <engine/textrender.h>
|
||||
#include <game/client/components/mapimages.h>
|
||||
|
||||
#include <game/client/component.h>
|
||||
|
@ -48,6 +49,11 @@ class CMenus : public CComponent
|
|||
static ColorRGBA ms_ColorTabbarActive;
|
||||
static ColorRGBA ms_ColorTabbarHover;
|
||||
|
||||
char m_aLocalStringHelper[1024];
|
||||
|
||||
float ButtonColorMulActive() { return 0.5f; }
|
||||
float ButtonColorMulHot() { return 1.5f; }
|
||||
float ButtonColorMulDefault() { return 1.0f; }
|
||||
float ButtonColorMul(const void *pID);
|
||||
|
||||
int DoButton_DemoPlayer(const void *pID, const char *pText, int Checked, const CUIRect *pRect);
|
||||
|
@ -88,6 +94,95 @@ class CMenus : public CComponent
|
|||
//static int ui_do_key_reader(void *id, const CUIRect *rect, int key);
|
||||
void UiDoGetButtons(int Start, int Stop, CUIRect View, CUIRect ScopeView);
|
||||
|
||||
// new gui with gui elements
|
||||
template<typename T>
|
||||
int DoButtonMenu(CUIElement &UIElement, const void *pID, T &&GetTextLambda, int Checked, const CUIRect *pRect, bool HintRequiresStringCheck, bool HintCanChangePositionOrSize = false, int Corners = CUI::CORNER_ALL, float r = 5.0f, float FontFactor = 0.0f, vec4 ColorHot = vec4(1.0f, 1.0f, 1.0f, 0.75f), vec4 Color = vec4(1, 1, 1, 0.5f), int AlignVertically = 1)
|
||||
{
|
||||
CUIRect Text = *pRect;
|
||||
Text.HMargin(pRect->h >= 20.0f ? 2.0f : 1.0f, &Text);
|
||||
Text.HMargin((Text.h * FontFactor) / 2.0f, &Text);
|
||||
|
||||
if(UIElement.Size() != 3 || HintRequiresStringCheck || HintCanChangePositionOrSize)
|
||||
{
|
||||
bool NeedsRecalc = UIElement.Size() != 3;
|
||||
if(HintCanChangePositionOrSize)
|
||||
{
|
||||
if(UIElement.Size() == 3)
|
||||
{
|
||||
if(UIElement.Get(0)->m_X != pRect->x || UIElement.Get(0)->m_Y != pRect->y || UIElement.Get(0)->m_Width != pRect->w || UIElement.Get(0)->m_Y != pRect->h)
|
||||
{
|
||||
NeedsRecalc = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
const char *pText = NULL;
|
||||
if(HintRequiresStringCheck)
|
||||
{
|
||||
if(UIElement.Size() == 3)
|
||||
{
|
||||
pText = GetTextLambda();
|
||||
if(str_comp(UIElement.Get(0)->m_Text.c_str(), pText) != 0)
|
||||
{
|
||||
NeedsRecalc = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(NeedsRecalc)
|
||||
{
|
||||
if(UIElement.Size() > 0)
|
||||
{
|
||||
UI()->ResetUIElement(UIElement);
|
||||
}
|
||||
|
||||
vec4 RealColor = Color;
|
||||
for(int i = 0; i < 3; ++i)
|
||||
{
|
||||
Color.a = RealColor.a;
|
||||
if(i == 0)
|
||||
Color.a *= ButtonColorMulActive();
|
||||
else if(i == 1)
|
||||
Color.a *= ButtonColorMulHot();
|
||||
else if(i == 2)
|
||||
Color.a *= ButtonColorMulDefault();
|
||||
Graphics()->SetColor(Color);
|
||||
|
||||
CUIElement::SUIElementRect NewRect;
|
||||
NewRect.m_UIRectQuadContainer = RenderTools()->CreateRoundRectQuadContainer(pRect->x, pRect->y, pRect->w, pRect->h, r, Corners);
|
||||
|
||||
NewRect.m_X = pRect->x;
|
||||
NewRect.m_Y = pRect->y;
|
||||
NewRect.m_Width = pRect->w;
|
||||
NewRect.m_Height = pRect->h;
|
||||
|
||||
if(i == 0)
|
||||
{
|
||||
if(pText == NULL)
|
||||
pText = GetTextLambda();
|
||||
NewRect.m_Text = pText;
|
||||
UI()->DoLabel(NewRect, &Text, pText, Text.h * ms_FontmodHeight, 0, -1, AlignVertically);
|
||||
}
|
||||
UIElement.Add(NewRect);
|
||||
}
|
||||
Graphics()->SetColor(1, 1, 1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
// render
|
||||
size_t Index = 2;
|
||||
if(UI()->ActiveItem() == pID)
|
||||
Index = 0;
|
||||
else if(UI()->HotItem() == pID)
|
||||
Index = 1;
|
||||
Graphics()->TextureClear();
|
||||
Graphics()->RenderQuadContainer(UIElement.Get(Index)->m_UIRectQuadContainer, -1);
|
||||
STextRenderColor ColorText(TextRender()->DefaultTextColor());
|
||||
STextRenderColor ColorTextOutline(TextRender()->DefaultTextOutlineColor());
|
||||
if(UIElement.Get(0)->m_UITextContainer != -1)
|
||||
TextRender()->RenderTextContainer(UIElement.Get(0)->m_UITextContainer, &ColorText, &ColorTextOutline);
|
||||
|
||||
return UI()->DoButtonLogic(pID, Checked, pRect);
|
||||
}
|
||||
|
||||
struct CListboxItem
|
||||
{
|
||||
int m_Visible;
|
||||
|
@ -186,6 +281,9 @@ protected:
|
|||
char m_aMessageBody[512];
|
||||
char m_aMessageButton[512];
|
||||
|
||||
CUIElement m_RefreshButton;
|
||||
CUIElement m_ConnectButton;
|
||||
|
||||
void PopupMessage(const char *pTopic, const char *pBody, const char *pButton);
|
||||
|
||||
// TODO: this is a bit ugly but.. well.. yeah
|
||||
|
|
|
@ -21,6 +21,16 @@
|
|||
|
||||
#include "menus.h"
|
||||
|
||||
static const int g_OffsetColFlagLock = 2;
|
||||
static const int g_OffsetColFav = g_OffsetColFlagLock + 3;
|
||||
static const int g_OffsetColOff = g_OffsetColFav + 3;
|
||||
static const int g_OffsetColName = g_OffsetColOff + 3;
|
||||
static const int g_OffsetColGameType = g_OffsetColName + 3;
|
||||
static const int g_OffsetColMap = g_OffsetColGameType + 3;
|
||||
static const int g_OffsetColPlayers = g_OffsetColMap + 3;
|
||||
static const int g_OffsetColPing = g_OffsetColPlayers + 3;
|
||||
static const int g_OffsetColVersion = g_OffsetColPing + 3;
|
||||
|
||||
void CMenus::RenderServerbrowserServerList(CUIRect View)
|
||||
{
|
||||
CUIRect Headers;
|
||||
|
@ -261,6 +271,25 @@ void CMenus::RenderServerbrowserServerList(CUIRect View)
|
|||
CUIRect Row;
|
||||
CUIRect SelectHitBox;
|
||||
|
||||
//initialize
|
||||
if(pItem->m_pUIElement == NULL)
|
||||
{
|
||||
pItem->m_pUIElement = UI()->GetNewUIElement();
|
||||
}
|
||||
|
||||
const int UIRectCount = 2 + (COL_VERSION + 1) * 3;
|
||||
|
||||
if(pItem->m_pUIElement->Size() != UIRectCount)
|
||||
{
|
||||
UI()->ResetUIElement(*pItem->m_pUIElement);
|
||||
|
||||
for(int UIElIndex = 0; UIElIndex < UIRectCount; ++UIElIndex)
|
||||
{
|
||||
CUIElement::SUIElementRect AddRect;
|
||||
pItem->m_pUIElement->Add(AddRect);
|
||||
}
|
||||
}
|
||||
|
||||
int Selected = str_comp(pItem->m_aAddress, g_Config.m_UiServerAddress) == 0; //selected_index==ItemIndex;
|
||||
|
||||
View.HSplitTop(ms_ListheaderHeight, &Row, &View);
|
||||
|
@ -299,7 +328,7 @@ void CMenus::RenderServerbrowserServerList(CUIRect View)
|
|||
{
|
||||
CUIRect r = Row;
|
||||
r.Margin(0.5f, &r);
|
||||
RenderTools()->DrawUIRect(&r, ColorRGBA(1, 1, 1, 0.5f), CUI::CORNER_ALL, 4.0f);
|
||||
RenderTools()->DrawUIElRect(*pItem->m_pUIElement->Get(0), &r, ColorRGBA(1, 1, 1, 0.5f), CUI::CORNER_ALL, 4.0f);
|
||||
}
|
||||
|
||||
// clip the selection
|
||||
|
@ -315,7 +344,7 @@ void CMenus::RenderServerbrowserServerList(CUIRect View)
|
|||
{
|
||||
CUIRect r = Row;
|
||||
r.Margin(0.5f, &r);
|
||||
RenderTools()->DrawUIRect(&r, ColorRGBA(1, 1, 1, 0.25f), CUI::CORNER_ALL, 4.0f);
|
||||
RenderTools()->DrawUIElRect(*pItem->m_pUIElement->Get(1), &r, ColorRGBA(1, 1, 1, 0.25f), CUI::CORNER_ALL, 4.0f);
|
||||
}
|
||||
|
||||
if(UI()->DoButtonLogic(pItem, "", Selected, &SelectHitBox))
|
||||
|
@ -364,10 +393,7 @@ void CMenus::RenderServerbrowserServerList(CUIRect View)
|
|||
}
|
||||
else if(ID == COL_NAME)
|
||||
{
|
||||
CTextCursor Cursor;
|
||||
float FontSize = 12.0f * UI()->Scale();
|
||||
TextRender()->SetCursor(&Cursor, Button.x, Button.y + (Button.h - FontSize) / 2.f, FontSize, TEXTFLAG_RENDER | TEXTFLAG_STOP_AT_END);
|
||||
Cursor.m_LineWidth = Button.w;
|
||||
|
||||
if(g_Config.m_BrFilterString[0] && (pItem->m_QuickSearchHit & IServerBrowser::QUICK_SERVERNAME))
|
||||
{
|
||||
|
@ -375,17 +401,17 @@ void CMenus::RenderServerbrowserServerList(CUIRect View)
|
|||
const char *pStr = str_find_nocase(pItem->m_aName, g_Config.m_BrFilterString);
|
||||
if(pStr)
|
||||
{
|
||||
TextRender()->TextEx(&Cursor, pItem->m_aName, (int)(pStr - pItem->m_aName));
|
||||
UI()->DoLabelStreamed(*pItem->m_pUIElement->Get(g_OffsetColName + 0), &Button, pItem->m_aName, FontSize, -1, Button.w, 1, true, (int)(pStr - pItem->m_aName));
|
||||
TextRender()->TextColor(0.4f, 0.4f, 1.0f, 1);
|
||||
TextRender()->TextEx(&Cursor, pStr, str_length(g_Config.m_BrFilterString));
|
||||
UI()->DoLabelStreamed(*pItem->m_pUIElement->Get(g_OffsetColName + 1), &Button, pStr, FontSize, -1, Button.w, 1, true, (int)str_length(g_Config.m_BrFilterString), &pItem->m_pUIElement->Get(g_OffsetColName + 0)->m_Cursor);
|
||||
TextRender()->TextColor(1, 1, 1, 1);
|
||||
TextRender()->TextEx(&Cursor, pStr + str_length(g_Config.m_BrFilterString), -1);
|
||||
UI()->DoLabelStreamed(*pItem->m_pUIElement->Get(g_OffsetColName + 2), &Button, pStr + str_length(g_Config.m_BrFilterString), FontSize, -1, Button.w, 1, true, -1, &pItem->m_pUIElement->Get(g_OffsetColName + 1)->m_Cursor);
|
||||
}
|
||||
else
|
||||
TextRender()->TextEx(&Cursor, pItem->m_aName, -1);
|
||||
UI()->DoLabelStreamed(*pItem->m_pUIElement->Get(g_OffsetColName), &Button, pItem->m_aName, FontSize, -1, Button.w, 1, true);
|
||||
}
|
||||
else
|
||||
TextRender()->TextEx(&Cursor, pItem->m_aName, -1);
|
||||
UI()->DoLabelStreamed(*pItem->m_pUIElement->Get(g_OffsetColName), &Button, pItem->m_aName, FontSize, -1, Button.w, 1, true);
|
||||
}
|
||||
else if(ID == COL_MAP)
|
||||
{
|
||||
|
@ -400,10 +426,7 @@ void CMenus::RenderServerbrowserServerList(CUIRect View)
|
|||
DoButton_Icon(IMAGE_BROWSEICONS, SPRITE_BROWSE_RANK, &Icon);
|
||||
}
|
||||
|
||||
CTextCursor Cursor;
|
||||
float FontSize = 12.0f * UI()->Scale();
|
||||
TextRender()->SetCursor(&Cursor, Button.x, Button.y + (Button.h - FontSize) / 2.f, 12.0f * UI()->Scale(), TEXTFLAG_RENDER | TEXTFLAG_STOP_AT_END);
|
||||
Cursor.m_LineWidth = Button.w;
|
||||
|
||||
if(g_Config.m_BrFilterString[0] && (pItem->m_QuickSearchHit & IServerBrowser::QUICK_MAPNAME))
|
||||
{
|
||||
|
@ -411,17 +434,17 @@ void CMenus::RenderServerbrowserServerList(CUIRect View)
|
|||
const char *pStr = str_find_nocase(pItem->m_aMap, g_Config.m_BrFilterString);
|
||||
if(pStr)
|
||||
{
|
||||
TextRender()->TextEx(&Cursor, pItem->m_aMap, (int)(pStr - pItem->m_aMap));
|
||||
UI()->DoLabelStreamed(*pItem->m_pUIElement->Get(g_OffsetColMap + 0), &Button, pItem->m_aMap, FontSize, -1, Button.w, 1, true, (int)(pStr - pItem->m_aMap));
|
||||
TextRender()->TextColor(0.4f, 0.4f, 1.0f, 1);
|
||||
TextRender()->TextEx(&Cursor, pStr, str_length(g_Config.m_BrFilterString));
|
||||
UI()->DoLabelStreamed(*pItem->m_pUIElement->Get(g_OffsetColMap + 1), &Button, pStr, FontSize, -1, Button.w, 1, true, (int)str_length(g_Config.m_BrFilterString), &pItem->m_pUIElement->Get(g_OffsetColMap + 0)->m_Cursor);
|
||||
TextRender()->TextColor(1, 1, 1, 1);
|
||||
TextRender()->TextEx(&Cursor, pStr + str_length(g_Config.m_BrFilterString), -1);
|
||||
UI()->DoLabelStreamed(*pItem->m_pUIElement->Get(g_OffsetColMap + 2), &Button, pStr + str_length(g_Config.m_BrFilterString), FontSize, -1, Button.w, 1, true, -1, &pItem->m_pUIElement->Get(g_OffsetColMap + 1)->m_Cursor);
|
||||
}
|
||||
else
|
||||
TextRender()->TextEx(&Cursor, pItem->m_aMap, -1);
|
||||
UI()->DoLabelStreamed(*pItem->m_pUIElement->Get(g_OffsetColMap), &Button, pItem->m_aMap, FontSize, -1, Button.w, 1, true);
|
||||
}
|
||||
else
|
||||
TextRender()->TextEx(&Cursor, pItem->m_aMap, -1);
|
||||
UI()->DoLabelStreamed(*pItem->m_pUIElement->Get(g_OffsetColMap), &Button, pItem->m_aMap, FontSize, -1, Button.w, 1, true);
|
||||
}
|
||||
else if(ID == COL_PLAYERS)
|
||||
{
|
||||
|
@ -437,7 +460,8 @@ void CMenus::RenderServerbrowserServerList(CUIRect View)
|
|||
str_format(aTemp, sizeof(aTemp), "%i/%i", pItem->m_NumFilteredPlayers, ServerBrowser()->Max(*pItem));
|
||||
if(g_Config.m_BrFilterString[0] && (pItem->m_QuickSearchHit & IServerBrowser::QUICK_PLAYER))
|
||||
TextRender()->TextColor(0.4f, 0.4f, 1.0f, 1);
|
||||
UI()->DoLabelScaled(&Button, aTemp, 12.0f, 1);
|
||||
float FontSize = 12.0f * UI()->Scale();
|
||||
UI()->DoLabelStreamed(*pItem->m_pUIElement->Get(g_OffsetColPlayers), &Button, aTemp, FontSize, -1, Button.w, 1, true);
|
||||
TextRender()->TextColor(1, 1, 1, 1);
|
||||
}
|
||||
else if(ID == COL_PING)
|
||||
|
@ -449,20 +473,19 @@ void CMenus::RenderServerbrowserServerList(CUIRect View)
|
|||
TextRender()->TextColor(rgb);
|
||||
}
|
||||
|
||||
UI()->DoLabelScaled(&Button, aTemp, 12.0f, 1);
|
||||
float FontSize = 12.0f * UI()->Scale();
|
||||
UI()->DoLabelStreamed(*pItem->m_pUIElement->Get(g_OffsetColPing), &Button, aTemp, FontSize, -1, Button.w, 1, true);
|
||||
TextRender()->TextColor(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
}
|
||||
else if(ID == COL_VERSION)
|
||||
{
|
||||
const char *pVersion = pItem->m_aVersion;
|
||||
UI()->DoLabelScaled(&Button, pVersion, 12.0f, 1);
|
||||
float FontSize = 12.0f * UI()->Scale();
|
||||
UI()->DoLabelStreamed(*pItem->m_pUIElement->Get(g_OffsetColVersion), &Button, pVersion, FontSize, -1, Button.w, 1, true);
|
||||
}
|
||||
else if(ID == COL_GAMETYPE)
|
||||
{
|
||||
CTextCursor Cursor;
|
||||
float FontSize = 12.0f * UI()->Scale();
|
||||
TextRender()->SetCursor(&Cursor, Button.x, Button.y + (Button.h - FontSize) / 2.f, 12.0f * UI()->Scale(), TEXTFLAG_RENDER | TEXTFLAG_STOP_AT_END);
|
||||
Cursor.m_LineWidth = Button.w;
|
||||
|
||||
if(g_Config.m_UiColorizeGametype)
|
||||
{
|
||||
|
@ -485,11 +508,11 @@ void CMenus::RenderServerbrowserServerList(CUIRect View)
|
|||
|
||||
ColorRGBA rgb = color_cast<ColorRGBA>(hsl);
|
||||
TextRender()->TextColor(rgb);
|
||||
TextRender()->TextEx(&Cursor, pItem->m_aGameType, -1);
|
||||
UI()->DoLabelStreamed(*pItem->m_pUIElement->Get(g_OffsetColGameType), &Button, pItem->m_aGameType, FontSize, -1, Button.w, 1, true);
|
||||
TextRender()->TextColor(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
}
|
||||
else
|
||||
TextRender()->TextEx(&Cursor, pItem->m_aGameType, -1);
|
||||
UI()->DoLabelStreamed(*pItem->m_pUIElement->Get(g_OffsetColGameType), &Button, pItem->m_aGameType, FontSize, -1, Button.w, 1, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -620,13 +643,16 @@ void CMenus::RenderServerbrowserServerList(CUIRect View)
|
|||
ButtonConnect.VSplitLeft(5.0f, NULL, &ButtonConnect);
|
||||
|
||||
static int s_RefreshButton = 0;
|
||||
char aBuf[64];
|
||||
if(ServerBrowser()->IsRefreshing())
|
||||
str_format(aBuf, sizeof(aBuf), "%s (%d%%)", Localize("Refresh"), ServerBrowser()->LoadingProgression());
|
||||
else
|
||||
str_copy(aBuf, Localize("Refresh"), sizeof(aBuf));
|
||||
auto Func = [this]() mutable -> const char * {
|
||||
if(ServerBrowser()->IsRefreshing())
|
||||
str_format(m_aLocalStringHelper, sizeof(m_aLocalStringHelper), "%s (%d%%)", Localize("Refresh"), ServerBrowser()->LoadingProgression());
|
||||
else
|
||||
str_copy(m_aLocalStringHelper, Localize("Refresh"), sizeof(m_aLocalStringHelper));
|
||||
|
||||
if(DoButton_Menu(&s_RefreshButton, aBuf, 0, &ButtonRefresh, NULL, CUI::CORNER_ALL) || Input()->KeyPress(KEY_F5) || (Input()->KeyPress(KEY_R) && (Input()->KeyIsPressed(KEY_LCTRL) || Input()->KeyIsPressed(KEY_RCTRL))))
|
||||
return m_aLocalStringHelper;
|
||||
};
|
||||
|
||||
if(DoButtonMenu(m_RefreshButton, &s_RefreshButton, Func, 0, &ButtonRefresh, true, false, CUI::CORNER_ALL) || Input()->KeyPress(KEY_F5) || (Input()->KeyPress(KEY_R) && (Input()->KeyIsPressed(KEY_LCTRL) || Input()->KeyIsPressed(KEY_RCTRL))))
|
||||
{
|
||||
if(g_Config.m_UiPage == PAGE_INTERNET)
|
||||
ServerBrowser()->Refresh(IServerBrowser::TYPE_INTERNET);
|
||||
|
@ -650,7 +676,10 @@ void CMenus::RenderServerbrowserServerList(CUIRect View)
|
|||
}
|
||||
|
||||
static int s_JoinButton = 0;
|
||||
if(DoButton_Menu(&s_JoinButton, Localize("Connect"), 0, &ButtonConnect, NULL, CUI::CORNER_ALL, 5, 0, vec4(0.7f, 1, 0.7f, 0.1f), vec4(0.7f, 1, 0.7f, 0.2f)) || m_EnterPressed)
|
||||
|
||||
if(DoButtonMenu(
|
||||
m_ConnectButton, &s_JoinButton, []() -> const char * { return Localize("Connect"); }, 0, &ButtonConnect, false, false, CUI::CORNER_ALL, 5, 0, vec4(0.7f, 1, 0.7f, 0.1f), vec4(0.7f, 1, 0.7f, 0.2f)) ||
|
||||
m_EnterPressed)
|
||||
{
|
||||
Client()->Connect(g_Config.m_UiServerAddress);
|
||||
m_EnterPressed = false;
|
||||
|
|
|
@ -1460,6 +1460,7 @@ void CMenus::RenderLanguageSelection(CUIRect MainView)
|
|||
{
|
||||
str_copy(g_Config.m_ClLanguagefile, s_Languages[s_SelectedLanguage].m_FileName, sizeof(g_Config.m_ClLanguagefile));
|
||||
g_Localization.Load(s_Languages[s_SelectedLanguage].m_FileName, Storage(), Console());
|
||||
GameClient()->OnLanguageChange();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -202,8 +202,8 @@ void CNamePlates::RenderNameplatePos(vec2 Position, const CNetObj_PlayerInfo *pP
|
|||
}
|
||||
}
|
||||
|
||||
TextRender()->TextColor(1, 1, 1, 1);
|
||||
TextRender()->TextOutlineColor(0.0f, 0.0f, 0.0f, 0.3f);
|
||||
TextRender()->TextColor(TextRender()->DefaultTextColor());
|
||||
TextRender()->TextOutlineColor(TextRender()->DefaultTextOutlineColor());
|
||||
|
||||
TextRender()->SetRenderFlags(0);
|
||||
}
|
||||
|
|
|
@ -947,6 +947,7 @@ void CGameClient::OnWindowResize()
|
|||
for(int i = 0; i < m_All.m_Num; i++)
|
||||
m_All.m_paComponents[i]->OnWindowResize();
|
||||
|
||||
UI()->OnWindowResize();
|
||||
TextRender()->OnWindowResize();
|
||||
}
|
||||
|
||||
|
@ -956,6 +957,11 @@ void CGameClient::OnWindowResizeCB(void *pUser)
|
|||
pClient->OnWindowResize();
|
||||
}
|
||||
|
||||
void CGameClient::OnLanguageChange()
|
||||
{
|
||||
UI()->OnLanguageChange();
|
||||
}
|
||||
|
||||
void CGameClient::OnRconType(bool UsernameReq)
|
||||
{
|
||||
m_pGameConsole->RequireUsername(UsernameReq);
|
||||
|
|
|
@ -378,6 +378,8 @@ public:
|
|||
void OnWindowResize();
|
||||
static void OnWindowResizeCB(void *pUser);
|
||||
|
||||
void OnLanguageChange();
|
||||
|
||||
virtual const char *GetItemName(int Type);
|
||||
virtual const char *Version();
|
||||
virtual const char *NetVersion();
|
||||
|
|
|
@ -456,6 +456,31 @@ int CRenderTools::CreateRoundRectQuadContainer(float x, float y, float w, float
|
|||
return ContainerIndex;
|
||||
}
|
||||
|
||||
void CRenderTools::DrawUIElRect(CUIElement::SUIElementRect &ElUIRect, const CUIRect *pRect, ColorRGBA Color, int Corners, float Rounding)
|
||||
{
|
||||
bool NeedsRecreate = false;
|
||||
if(ElUIRect.m_UIRectQuadContainer == -1 || ElUIRect.m_X != pRect->x || ElUIRect.m_Y != pRect->y || ElUIRect.m_Width != pRect->w || ElUIRect.m_Height != pRect->h)
|
||||
{
|
||||
if(ElUIRect.m_UIRectQuadContainer != -1)
|
||||
Graphics()->DeleteQuadContainer(ElUIRect.m_UIRectQuadContainer);
|
||||
NeedsRecreate = true;
|
||||
}
|
||||
if(NeedsRecreate)
|
||||
{
|
||||
ElUIRect.m_X = pRect->x;
|
||||
ElUIRect.m_Y = pRect->y;
|
||||
ElUIRect.m_Width = pRect->w;
|
||||
ElUIRect.m_Height = pRect->h;
|
||||
|
||||
Graphics()->SetColor(Color);
|
||||
ElUIRect.m_UIRectQuadContainer = CreateRoundRectQuadContainer(pRect->x, pRect->y, pRect->w, pRect->h, Rounding, Corners);
|
||||
Graphics()->SetColor(1, 1, 1, 1);
|
||||
}
|
||||
|
||||
Graphics()->TextureClear();
|
||||
Graphics()->RenderQuadContainer(ElUIRect.m_UIRectQuadContainer, -1);
|
||||
}
|
||||
|
||||
void CRenderTools::DrawRoundRect(float x, float y, float w, float h, float r)
|
||||
{
|
||||
DrawRoundRectExt(x, y, w, h, r, 0xf);
|
||||
|
|
|
@ -85,6 +85,8 @@ public:
|
|||
|
||||
int CreateRoundRectQuadContainer(float x, float y, float w, float h, float r, int Corners);
|
||||
|
||||
void DrawUIElRect(CUIElement::SUIElementRect &ElUIRect, const CUIRect *pRect, ColorRGBA Color, int Corners, float Rounding);
|
||||
|
||||
void DrawUIRect(const CUIRect *pRect, ColorRGBA Color, int Corners, float Rounding);
|
||||
void DrawUIRect4(const CUIRect *pRect, vec4 ColorTopLeft, vec4 ColorTopRight, vec4 ColorBottomLeft, vec4 ColorBottomRight, int Corners, float Rounding);
|
||||
|
||||
|
|
|
@ -8,6 +8,11 @@
|
|||
#include <engine/shared/config.h>
|
||||
#include <engine/textrender.h>
|
||||
|
||||
void CUIElement::Init(CUI *pUI)
|
||||
{
|
||||
pUI->AddUIElement(this);
|
||||
}
|
||||
|
||||
/********************************************************
|
||||
UI
|
||||
*********************************************************/
|
||||
|
@ -32,6 +37,62 @@ CUI::CUI()
|
|||
m_Screen.h = 480.0f;
|
||||
}
|
||||
|
||||
CUI::~CUI()
|
||||
{
|
||||
for(CUIElement *&pEl : m_OwnUIElements)
|
||||
{
|
||||
delete pEl;
|
||||
}
|
||||
m_OwnUIElements.clear();
|
||||
}
|
||||
|
||||
CUIElement *CUI::GetNewUIElement()
|
||||
{
|
||||
CUIElement *pNewEl = new CUIElement(this);
|
||||
|
||||
m_OwnUIElements.push_back(pNewEl);
|
||||
|
||||
return pNewEl;
|
||||
}
|
||||
|
||||
void CUI::AddUIElement(CUIElement *pElement)
|
||||
{
|
||||
m_UIElements.push_back(pElement);
|
||||
}
|
||||
|
||||
void CUI::ResetUIElement(CUIElement &UIElement)
|
||||
{
|
||||
for(CUIElement::SUIElementRect &Rect : UIElement.m_UIRects)
|
||||
{
|
||||
if(Rect.m_UIRectQuadContainer != -1)
|
||||
Graphics()->DeleteQuadContainer(Rect.m_UIRectQuadContainer);
|
||||
Rect.m_UIRectQuadContainer = -1;
|
||||
if(Rect.m_UITextContainer != -1)
|
||||
TextRender()->DeleteTextContainer(Rect.m_UITextContainer);
|
||||
Rect.m_UITextContainer = -1;
|
||||
}
|
||||
|
||||
UIElement.Clear();
|
||||
}
|
||||
|
||||
void CUI::OnElementsReset()
|
||||
{
|
||||
for(CUIElement *pEl : m_UIElements)
|
||||
{
|
||||
ResetUIElement(*pEl);
|
||||
}
|
||||
}
|
||||
|
||||
void CUI::OnWindowResize()
|
||||
{
|
||||
OnElementsReset();
|
||||
}
|
||||
|
||||
void CUI::OnLanguageChange()
|
||||
{
|
||||
OnElementsReset();
|
||||
}
|
||||
|
||||
int CUI::Update(float Mx, float My, float Mwx, float Mwy, int Buttons)
|
||||
{
|
||||
m_MouseX = Mx;
|
||||
|
@ -274,6 +335,11 @@ void CUIRect::HMargin(float Cut, CUIRect *pOtherRect) const
|
|||
}
|
||||
|
||||
int CUI::DoButtonLogic(const void *pID, const char *pText, int Checked, const CUIRect *pRect)
|
||||
{
|
||||
return DoButtonLogic(pID, Checked, pRect);
|
||||
}
|
||||
|
||||
int CUI::DoButtonLogic(const void *pID, int Checked, const CUIRect *pRect)
|
||||
{
|
||||
// logic
|
||||
int ReturnValue = 0;
|
||||
|
@ -403,3 +469,94 @@ void CUI::DoLabelScaled(const CUIRect *r, const char *pText, float Size, int Ali
|
|||
{
|
||||
DoLabel(r, pText, Size * Scale(), Align, MaxWidth, AlignVertically);
|
||||
}
|
||||
|
||||
void CUI::DoLabel(CUIElement::SUIElementRect &RectEl, const CUIRect *pRect, const char *pText, float Size, int Align, int MaxWidth, int AlignVertically, bool StopAtEnd, int StrLen, CTextCursor *pReadCursor)
|
||||
{
|
||||
float AlignedSize = 0;
|
||||
float MaxCharacterHeightInLine = 0;
|
||||
float tw = TextRender()->TextWidth(0, Size, pText, -1, MaxWidth, &AlignedSize, &MaxCharacterHeightInLine);
|
||||
float AlignmentVert = pRect->y + (pRect->h - AlignedSize) / 2.f;
|
||||
float AlignmentHori = 0;
|
||||
|
||||
CTextCursor Cursor;
|
||||
|
||||
int Flags = TEXTFLAG_RENDER | (StopAtEnd ? TEXTFLAG_STOP_AT_END : 0);
|
||||
|
||||
if(AlignVertically == 0)
|
||||
{
|
||||
AlignmentVert = pRect->y + (pRect->h - AlignedSize) / 2.f - (AlignedSize - MaxCharacterHeightInLine) / 2.f;
|
||||
}
|
||||
if(Align == 0)
|
||||
{
|
||||
AlignmentHori = pRect->x + (pRect->w - tw) / 2.f;
|
||||
}
|
||||
else if(Align < 0)
|
||||
{
|
||||
AlignmentHori = pRect->x;
|
||||
}
|
||||
else if(Align > 0)
|
||||
{
|
||||
AlignmentHori = pRect->x + pRect->w - tw;
|
||||
}
|
||||
|
||||
if(pReadCursor)
|
||||
{
|
||||
Cursor = *pReadCursor;
|
||||
}
|
||||
else
|
||||
{
|
||||
TextRender()->SetCursor(&Cursor, AlignmentHori, AlignmentVert, Size, Flags);
|
||||
}
|
||||
Cursor.m_LineWidth = MaxWidth;
|
||||
|
||||
RectEl.m_UITextContainer = TextRender()->CreateTextContainer(&Cursor, pText, StrLen);
|
||||
RectEl.m_Cursor = Cursor;
|
||||
}
|
||||
|
||||
void CUI::DoLabelStreamed(CUIElement::SUIElementRect &RectEl, const CUIRect *pRect, const char *pText, float Size, int Align, int MaxWidth, int AlignVertically, bool StopAtEnd, int StrLen, CTextCursor *pReadCursor)
|
||||
{
|
||||
bool NeedsRecreate = false;
|
||||
if(RectEl.m_UITextContainer == -1 || RectEl.m_X != pRect->x || RectEl.m_Y != pRect->y || RectEl.m_Width != pRect->w || RectEl.m_Height != pRect->h)
|
||||
{
|
||||
NeedsRecreate = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(StrLen <= -1)
|
||||
{
|
||||
if(str_comp(RectEl.m_Text.c_str(), pText) != 0)
|
||||
NeedsRecreate = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(StrLen != (int)RectEl.m_Text.size() || str_comp_num(RectEl.m_Text.c_str(), pText, StrLen) != 0)
|
||||
NeedsRecreate = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(NeedsRecreate)
|
||||
{
|
||||
if(RectEl.m_UITextContainer != -1)
|
||||
TextRender()->DeleteTextContainer(RectEl.m_UITextContainer);
|
||||
RectEl.m_UITextContainer = -1;
|
||||
|
||||
RectEl.m_X = pRect->x;
|
||||
RectEl.m_Y = pRect->y;
|
||||
RectEl.m_Width = pRect->w;
|
||||
RectEl.m_Height = pRect->h;
|
||||
|
||||
if(StrLen > 0)
|
||||
RectEl.m_Text = std::string(pText, StrLen);
|
||||
else if(StrLen < 0)
|
||||
RectEl.m_Text = pText;
|
||||
else
|
||||
RectEl.m_Text.clear();
|
||||
|
||||
DoLabel(RectEl, pRect, pText, Size, Align, MaxWidth, AlignVertically, StopAtEnd, StrLen, pReadCursor);
|
||||
}
|
||||
|
||||
STextRenderColor ColorText(TextRender()->DefaultTextColor());
|
||||
STextRenderColor ColorTextOutline(TextRender()->DefaultTextOutlineColor());
|
||||
if(RectEl.m_UITextContainer != -1)
|
||||
TextRender()->RenderTextContainer(RectEl.m_UITextContainer, &ColorText, &ColorTextOutline);
|
||||
}
|
||||
|
|
|
@ -3,6 +3,11 @@
|
|||
#ifndef GAME_CLIENT_UI_H
|
||||
#define GAME_CLIENT_UI_H
|
||||
|
||||
#include <base/system.h>
|
||||
#include <engine/textrender.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
class CUIRect
|
||||
{
|
||||
// TODO: Refactor: Redo UI scaling
|
||||
|
@ -97,6 +102,65 @@ public:
|
|||
void HMargin(float Cut, CUIRect *pOtherRect) const;
|
||||
};
|
||||
|
||||
class CUI;
|
||||
|
||||
class CUIElement
|
||||
{
|
||||
friend class CUI;
|
||||
|
||||
CUIElement(CUI *pUI) { Init(pUI); }
|
||||
|
||||
public:
|
||||
struct SUIElementRect
|
||||
{
|
||||
public:
|
||||
int m_UIRectQuadContainer;
|
||||
int m_UITextContainer;
|
||||
|
||||
float m_X;
|
||||
float m_Y;
|
||||
float m_Width;
|
||||
float m_Height;
|
||||
|
||||
std::string m_Text;
|
||||
|
||||
CTextCursor m_Cursor;
|
||||
|
||||
SUIElementRect() :
|
||||
m_UIRectQuadContainer(-1), m_UITextContainer(-1), m_X(-1), m_Y(-1), m_Width(-1), m_Height(-1)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
protected:
|
||||
std::vector<SUIElementRect> m_UIRects;
|
||||
|
||||
// used for marquees or other user implemented things
|
||||
int64 m_ElementTime;
|
||||
|
||||
public:
|
||||
CUIElement() = default;
|
||||
|
||||
void Init(CUI *pUI);
|
||||
|
||||
SUIElementRect *Get(size_t Index)
|
||||
{
|
||||
return &m_UIRects[Index];
|
||||
}
|
||||
|
||||
size_t Size()
|
||||
{
|
||||
return m_UIRects.size();
|
||||
}
|
||||
|
||||
void Clear() { m_UIRects.clear(); }
|
||||
|
||||
void Add(SUIElementRect &ElRect)
|
||||
{
|
||||
m_UIRects.push_back(ElRect);
|
||||
}
|
||||
};
|
||||
|
||||
class CUI
|
||||
{
|
||||
const void *m_pHotItem;
|
||||
|
@ -112,6 +176,9 @@ class CUI
|
|||
class IGraphics *m_pGraphics;
|
||||
class ITextRender *m_pTextRender;
|
||||
|
||||
std::vector<CUIElement *> m_OwnUIElements; // ui elements maintained by CUI class
|
||||
std::vector<CUIElement *> m_UIElements;
|
||||
|
||||
public:
|
||||
// TODO: Refactor: Fill this in
|
||||
void SetGraphics(class IGraphics *pGraphics, class ITextRender *pTextRender)
|
||||
|
@ -123,6 +190,16 @@ public:
|
|||
class ITextRender *TextRender() { return m_pTextRender; }
|
||||
|
||||
CUI();
|
||||
~CUI();
|
||||
|
||||
void ResetUIElement(CUIElement &UIElement);
|
||||
|
||||
CUIElement *GetNewUIElement();
|
||||
|
||||
void AddUIElement(CUIElement *pElement);
|
||||
void OnElementsReset();
|
||||
void OnWindowResize();
|
||||
void OnLanguageChange();
|
||||
|
||||
enum
|
||||
{
|
||||
|
@ -173,12 +250,16 @@ public:
|
|||
void SetScale(float s);
|
||||
float Scale();
|
||||
|
||||
int DoButtonLogic(const void *pID, int Checked, const CUIRect *pRect);
|
||||
int DoButtonLogic(const void *pID, const char *pText /* TODO: Refactor: Remove */, int Checked, const CUIRect *pRect);
|
||||
int DoPickerLogic(const void *pID, const CUIRect *pRect, float *pX, float *pY);
|
||||
|
||||
// TODO: Refactor: Remove this?
|
||||
void DoLabel(const CUIRect *pRect, const char *pText, float Size, int Align, int MaxWidth = -1, int AlignVertically = 1);
|
||||
void DoLabelScaled(const CUIRect *pRect, const char *pText, float Size, int Align, int MaxWidth = -1, int AlignVertically = 1);
|
||||
|
||||
void DoLabel(CUIElement::SUIElementRect &RectEl, const CUIRect *pRect, const char *pText, float Size, int Align, int MaxWidth = -1, int AlignVertically = 1, bool StopAtEnd = false, int StrLen = -1, class CTextCursor *pReadCursor = NULL);
|
||||
void DoLabelStreamed(CUIElement::SUIElementRect &RectEl, const CUIRect *pRect, const char *pText, float Size, int Align, int MaxWidth = -1, int AlignVertically = 1, bool StopAtEnd = false, int StrLen = -1, class CTextCursor *pReadCursor = NULL);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue