mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-18 22:18:19 +00:00
0b57d56f48
Move the "Filter", "Info" and "Friends" tabs to the top, above the tab content. Use icons instead of text for the tabs. Use animator to animate the tabs on mouse-over. Closes #6613. Make spacings, corners and font sizes used in the filter, details and friends tabs more consistent. Remove some unnecessary dark UI rect backgrounds. Improve alignment of the number of friends with the heart icon for entries in the server list. Improve layout of countries and types filters. Make the filters scrollable when there are many entries. Refactor most of the server browser in preparation for replacing the DDNet and KoG tabs with a community filter, which will work like the countries and types filters. Split rendering of different server browser sections into multiple functions to improve readability. Reduce duplicate code for the countries and types filters.
325 lines
13 KiB
C++
325 lines
13 KiB
C++
/* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */
|
|
/* If you are missing that file, acquire a complete release at teeworlds.com. */
|
|
#ifndef ENGINE_TEXTRENDER_H
|
|
#define ENGINE_TEXTRENDER_H
|
|
#include "kernel.h"
|
|
|
|
#include <base/color.h>
|
|
|
|
#include <engine/graphics.h>
|
|
|
|
#include <cstdint>
|
|
#include <memory>
|
|
|
|
enum
|
|
{
|
|
TEXTFLAG_RENDER = 1 << 0,
|
|
TEXTFLAG_DISALLOW_NEWLINE = 1 << 1,
|
|
TEXTFLAG_STOP_AT_END = 1 << 2,
|
|
TEXTFLAG_ELLIPSIS_AT_END = 1 << 3,
|
|
};
|
|
|
|
enum ETextAlignment
|
|
{
|
|
TEXTALIGN_LEFT = 0,
|
|
TEXTALIGN_CENTER = 1 << 1,
|
|
TEXTALIGN_RIGHT = 1 << 2,
|
|
TEXTALIGN_TOP = 0, // this is also 0, so the default alignment is top-left
|
|
TEXTALIGN_MIDDLE = 1 << 3,
|
|
TEXTALIGN_BOTTOM = 1 << 4,
|
|
|
|
TEXTALIGN_TL = TEXTALIGN_TOP | TEXTALIGN_LEFT,
|
|
TEXTALIGN_TC = TEXTALIGN_TOP | TEXTALIGN_CENTER,
|
|
TEXTALIGN_TR = TEXTALIGN_TOP | TEXTALIGN_RIGHT,
|
|
TEXTALIGN_ML = TEXTALIGN_MIDDLE | TEXTALIGN_LEFT,
|
|
TEXTALIGN_MC = TEXTALIGN_MIDDLE | TEXTALIGN_CENTER,
|
|
TEXTALIGN_MR = TEXTALIGN_MIDDLE | TEXTALIGN_RIGHT,
|
|
TEXTALIGN_BL = TEXTALIGN_BOTTOM | TEXTALIGN_LEFT,
|
|
TEXTALIGN_BC = TEXTALIGN_BOTTOM | TEXTALIGN_CENTER,
|
|
TEXTALIGN_BR = TEXTALIGN_BOTTOM | TEXTALIGN_RIGHT,
|
|
|
|
TEXTALIGN_MASK_HORIZONTAL = TEXTALIGN_LEFT | TEXTALIGN_CENTER | TEXTALIGN_RIGHT,
|
|
TEXTALIGN_MASK_VERTICAL = TEXTALIGN_TOP | TEXTALIGN_MIDDLE | TEXTALIGN_BOTTOM,
|
|
};
|
|
|
|
enum ETextRenderFlags
|
|
{
|
|
TEXT_RENDER_FLAG_NO_X_BEARING = 1 << 0,
|
|
TEXT_RENDER_FLAG_NO_Y_BEARING = 1 << 1,
|
|
TEXT_RENDER_FLAG_ONLY_ADVANCE_WIDTH = 1 << 2,
|
|
TEXT_RENDER_FLAG_NO_PIXEL_ALIGMENT = 1 << 3,
|
|
TEXT_RENDER_FLAG_KERNING = 1 << 4,
|
|
TEXT_RENDER_FLAG_NO_OVERSIZE = 1 << 5,
|
|
TEXT_RENDER_FLAG_NO_FIRST_CHARACTER_X_BEARING = 1 << 6,
|
|
TEXT_RENDER_FLAG_NO_LAST_CHARACTER_ADVANCE = 1 << 7,
|
|
TEXT_RENDER_FLAG_NO_AUTOMATIC_QUAD_UPLOAD = 1 << 8,
|
|
// text is only rendered once and then discarded (a hint for buffer creation)
|
|
TEXT_RENDER_FLAG_ONE_TIME_USE = 1 << 9,
|
|
};
|
|
|
|
enum class EFontPreset
|
|
{
|
|
DEFAULT_FONT,
|
|
ICON_FONT,
|
|
};
|
|
|
|
namespace FontIcons {
|
|
// Each font icon is named according to its official name in Font Awesome
|
|
MAYBE_UNUSED static const char *FONT_ICON_PLUS = "+";
|
|
MAYBE_UNUSED static const char *FONT_ICON_LOCK = "\xEF\x80\xA3";
|
|
MAYBE_UNUSED static const char *FONT_ICON_MAGNIFYING_GLASS = "\xEF\x80\x82";
|
|
MAYBE_UNUSED static const char *FONT_ICON_HEART = "\xEF\x80\x84";
|
|
MAYBE_UNUSED static const char *FONT_ICON_STAR = "\xEF\x80\x85";
|
|
MAYBE_UNUSED static const char *FONT_ICON_CHECK = "\xEF\x80\x8C";
|
|
MAYBE_UNUSED static const char *FONT_ICON_XMARK = "\xEF\x80\x8D";
|
|
MAYBE_UNUSED static const char *FONT_ICON_CIRCLE = "\xEF\x84\x91";
|
|
MAYBE_UNUSED static const char *FONT_ICON_ARROW_ROTATE_LEFT = "\xEF\x83\xA2";
|
|
MAYBE_UNUSED static const char *FONT_ICON_ARROW_ROTATE_RIGHT = "\xEF\x80\x9E";
|
|
MAYBE_UNUSED static const char *FONT_ICON_CERTIFICATE = "\xEF\x82\xA3";
|
|
MAYBE_UNUSED static const char *FONT_ICON_FLAG_CHECKERED = "\xEF\x84\x9E";
|
|
MAYBE_UNUSED static const char *FONT_ICON_BAN = "\xEF\x81\x9E";
|
|
MAYBE_UNUSED static const char *FONT_ICON_CIRCLE_CHEVRON_DOWN = "\xEF\x84\xBA";
|
|
MAYBE_UNUSED static const char *FONT_ICON_SQUARE_MINUS = "\xEF\x85\x86";
|
|
MAYBE_UNUSED static const char *FONT_ICON_SQUARE_PLUS = "\xEF\x83\xBE";
|
|
MAYBE_UNUSED static const char *FONT_ICON_SORT_UP = "\xEF\x83\x9E";
|
|
MAYBE_UNUSED static const char *FONT_ICON_SORT_DOWN = "\xEF\x83\x9D";
|
|
|
|
MAYBE_UNUSED static const char *FONT_ICON_HOUSE = "\xEF\x80\x95";
|
|
MAYBE_UNUSED static const char *FONT_ICON_NEWSPAPER = "\xEF\x87\xAA";
|
|
MAYBE_UNUSED static const char *FONT_ICON_POWER_OFF = "\xEF\x80\x91";
|
|
MAYBE_UNUSED static const char *FONT_ICON_GEAR = "\xEF\x80\x93";
|
|
MAYBE_UNUSED static const char *FONT_ICON_PEN_TO_SQUARE = "\xEF\x81\x84";
|
|
MAYBE_UNUSED static const char *FONT_ICON_CLAPPERBOARD = "\xEE\x84\xB1";
|
|
MAYBE_UNUSED static const char *FONT_ICON_EARTH_AMERICAS = "\xEF\x95\xBD";
|
|
MAYBE_UNUSED static const char *FONT_ICON_LIST_UL = "\xEF\x83\x8A";
|
|
MAYBE_UNUSED static const char *FONT_ICON_INFO = "\xEF\x84\xA9";
|
|
|
|
MAYBE_UNUSED static const char *FONT_ICON_SLASH = "\xEF\x9C\x95";
|
|
MAYBE_UNUSED static const char *FONT_ICON_PLAY = "\xEF\x81\x8B";
|
|
MAYBE_UNUSED static const char *FONT_ICON_PAUSE = "\xEF\x81\x8C";
|
|
MAYBE_UNUSED static const char *FONT_ICON_STOP = "\xEF\x81\x8D";
|
|
MAYBE_UNUSED static const char *FONT_ICON_CHEVRON_LEFT = "\xEF\x81\x93";
|
|
MAYBE_UNUSED static const char *FONT_ICON_CHEVRON_RIGHT = "\xEF\x81\x94";
|
|
MAYBE_UNUSED static const char *FONT_ICON_CHEVRON_UP = "\xEF\x81\xB7";
|
|
MAYBE_UNUSED static const char *FONT_ICON_CHEVRON_DOWN = "\xEF\x81\xB8";
|
|
MAYBE_UNUSED static const char *FONT_ICON_BACKWARD = "\xEF\x81\x8A";
|
|
MAYBE_UNUSED static const char *FONT_ICON_FORWARD = "\xEF\x81\x8E";
|
|
MAYBE_UNUSED static const char *FONT_ICON_RIGHT_FROM_BRACKET = "\xEF\x8B\xB5";
|
|
MAYBE_UNUSED static const char *FONT_ICON_RIGHT_TO_BRACKET = "\xEF\x8B\xB6";
|
|
MAYBE_UNUSED static const char *FONT_ICON_ARROW_UP_RIGHT_FROM_SQUARE = "\xEF\x82\x8E";
|
|
MAYBE_UNUSED static const char *FONT_ICON_BACKWARD_STEP = "\xEF\x81\x88";
|
|
MAYBE_UNUSED static const char *FONT_ICON_FORWARD_STEP = "\xEF\x81\x91";
|
|
MAYBE_UNUSED static const char *FONT_ICON_BACKWARD_FAST = "\xEF\x81\x89";
|
|
MAYBE_UNUSED static const char *FONT_ICON_FORWARD_FAST = "\xEF\x81\x90";
|
|
MAYBE_UNUSED static const char *FONT_ICON_KEYBOARD = "\xE2\x8C\xA8";
|
|
MAYBE_UNUSED static const char *FONT_ICON_ELLIPSIS = "\xEF\x85\x81";
|
|
|
|
MAYBE_UNUSED static const char *FONT_ICON_FOLDER = "\xEF\x81\xBB";
|
|
MAYBE_UNUSED static const char *FONT_ICON_FOLDER_TREE = "\xEF\xA0\x82";
|
|
MAYBE_UNUSED static const char *FONT_ICON_FILM = "\xEF\x80\x88";
|
|
MAYBE_UNUSED static const char *FONT_ICON_MAP = "\xEF\x89\xB9";
|
|
MAYBE_UNUSED static const char *FONT_ICON_IMAGE = "\xEF\x80\xBE";
|
|
MAYBE_UNUSED static const char *FONT_ICON_MUSIC = "\xEF\x80\x81";
|
|
MAYBE_UNUSED static const char *FONT_ICON_FILE = "\xEF\x85\x9B";
|
|
|
|
MAYBE_UNUSED static const char *FONT_ICON_PENCIL = "\xEF\x8C\x83";
|
|
MAYBE_UNUSED static const char *FONT_ICON_TRASH = "\xEF\x87\xB8";
|
|
|
|
MAYBE_UNUSED static const char *FONT_ICON_ARROWS_LEFT_RIGHT = "\xEF\x8C\xB7";
|
|
MAYBE_UNUSED static const char *FONT_ICON_ARROWS_UP_DOWN = "\xEF\x81\xBD";
|
|
MAYBE_UNUSED static const char *FONT_ICON_CIRCLE_PLAY = "\xEF\x85\x84";
|
|
MAYBE_UNUSED static const char *FONT_ICON_BORDER_ALL = "\xEF\xA1\x8C";
|
|
MAYBE_UNUSED static const char *FONT_ICON_EYE = "\xEF\x81\xAE";
|
|
MAYBE_UNUSED static const char *FONT_ICON_EYE_SLASH = "\xEF\x81\xB0";
|
|
|
|
MAYBE_UNUSED static const char *FONT_ICON_DICE_ONE = "\xEF\x94\xA5";
|
|
MAYBE_UNUSED static const char *FONT_ICON_DICE_TWO = "\xEF\x94\xA8";
|
|
MAYBE_UNUSED static const char *FONT_ICON_DICE_THREE = "\xEF\x94\xA7";
|
|
MAYBE_UNUSED static const char *FONT_ICON_DICE_FOUR = "\xEF\x94\xA4";
|
|
MAYBE_UNUSED static const char *FONT_ICON_DICE_FIVE = "\xEF\x94\xA3";
|
|
MAYBE_UNUSED static const char *FONT_ICON_DICE_SIX = "\xEF\x94\xA6";
|
|
} // end namespace FontIcons
|
|
|
|
enum ETextCursorSelectionMode
|
|
{
|
|
// ignore any kind of selection
|
|
TEXT_CURSOR_SELECTION_MODE_NONE = 0,
|
|
// calculates the selection based on the mouse press and release cursor position
|
|
TEXT_CURSOR_SELECTION_MODE_CALCULATE,
|
|
// sets the selection based on the character start and end count(these values have to be decoded character offsets)
|
|
TEXT_CURSOR_SELECTION_MODE_SET,
|
|
};
|
|
|
|
enum ETextCursorCursorMode
|
|
{
|
|
// ignore any kind of cursor
|
|
TEXT_CURSOR_CURSOR_MODE_NONE = 0,
|
|
// calculates the cursor based on the mouse release cursor position
|
|
TEXT_CURSOR_CURSOR_MODE_CALCULATE,
|
|
// sets the cursor based on the current character (this value has to be decoded character offset)
|
|
TEXT_CURSOR_CURSOR_MODE_SET,
|
|
};
|
|
|
|
struct STextBoundingBox
|
|
{
|
|
float m_X;
|
|
float m_Y;
|
|
float m_W;
|
|
float m_H;
|
|
|
|
float Right() const { return m_X + m_W; }
|
|
float Bottom() const { return m_Y + m_H; }
|
|
vec2 Size() const { return vec2(m_W, m_H); }
|
|
void MoveBy(vec2 Offset)
|
|
{
|
|
m_X += Offset.x;
|
|
m_Y += Offset.y;
|
|
}
|
|
};
|
|
|
|
class CTextCursor
|
|
{
|
|
public:
|
|
int m_Flags;
|
|
int m_LineCount;
|
|
int m_GlyphCount;
|
|
int m_CharCount;
|
|
int m_MaxLines;
|
|
|
|
float m_StartX;
|
|
float m_StartY;
|
|
float m_LineWidth;
|
|
float m_X, m_Y;
|
|
float m_MaxCharacterHeight;
|
|
float m_LongestLineWidth;
|
|
|
|
float m_FontSize;
|
|
float m_AlignedFontSize;
|
|
|
|
ETextCursorSelectionMode m_CalculateSelectionMode;
|
|
float m_SelectionHeightFactor;
|
|
|
|
// these coordinates are respected if selection mode is set to calculate @see ETextCursorSelectionMode
|
|
vec2 m_PressMouse;
|
|
// these coordinates are respected if selection/cursor mode is set to calculate @see ETextCursorSelectionMode / @see ETextCursorCursorMode
|
|
vec2 m_ReleaseMouse;
|
|
|
|
// note m_SelectionStart can be bigger than m_SelectionEnd, depending on how the mouse cursor was dragged
|
|
// also note, that these are the character offsets decoded
|
|
int m_SelectionStart;
|
|
int m_SelectionEnd;
|
|
|
|
ETextCursorCursorMode m_CursorMode;
|
|
bool m_ForceCursorRendering;
|
|
// note this is the decoded character offset
|
|
int m_CursorCharacter;
|
|
vec2 m_CursorRenderedPosition;
|
|
|
|
float Height() const
|
|
{
|
|
return m_LineCount * m_AlignedFontSize;
|
|
}
|
|
|
|
STextBoundingBox BoundingBox() const
|
|
{
|
|
return {m_StartX, m_StartY, m_LongestLineWidth, Height()};
|
|
}
|
|
};
|
|
|
|
struct STextContainerUsages
|
|
{
|
|
int m_Dummy = 0;
|
|
};
|
|
|
|
struct STextContainerIndex
|
|
{
|
|
int m_Index;
|
|
std::shared_ptr<STextContainerUsages> m_UseCount =
|
|
std::make_shared<STextContainerUsages>(STextContainerUsages());
|
|
|
|
STextContainerIndex() { Reset(); }
|
|
bool Valid() const { return m_Index >= 0; }
|
|
void Reset() { m_Index = -1; }
|
|
};
|
|
|
|
struct STextSizeProperties
|
|
{
|
|
float *m_pHeight = nullptr;
|
|
float *m_pAlignedFontSize = nullptr;
|
|
float *m_pMaxCharacterHeightInLine = nullptr;
|
|
int *m_pLineCount = nullptr;
|
|
};
|
|
|
|
class ITextRender : public IInterface
|
|
{
|
|
MACRO_INTERFACE("textrender", 0)
|
|
public:
|
|
virtual void SetCursor(CTextCursor *pCursor, float x, float y, float FontSize, int Flags) const = 0;
|
|
virtual void MoveCursor(CTextCursor *pCursor, float x, float y) const = 0;
|
|
virtual void SetCursorPosition(CTextCursor *pCursor, float x, float y) const = 0;
|
|
|
|
virtual void LoadFonts() = 0;
|
|
virtual void SetFontPreset(EFontPreset FontPreset) = 0;
|
|
virtual void SetFontLanguageVariant(const char *pLanguageFile) = 0;
|
|
|
|
virtual void SetRenderFlags(unsigned Flags) = 0;
|
|
virtual unsigned GetRenderFlags() const = 0;
|
|
|
|
ColorRGBA DefaultTextColor() const { return ColorRGBA(1, 1, 1, 1); }
|
|
ColorRGBA DefaultTextOutlineColor() const { return ColorRGBA(0, 0, 0, 0.3f); }
|
|
ColorRGBA DefaultTextSelectionColor() const { return ColorRGBA(1.0f, 1.0f, 1.0f, 0.5f); }
|
|
|
|
//
|
|
virtual void TextEx(CTextCursor *pCursor, const char *pText, int Length = -1) = 0;
|
|
virtual bool CreateTextContainer(STextContainerIndex &TextContainerIndex, CTextCursor *pCursor, const char *pText, int Length = -1) = 0;
|
|
virtual void AppendTextContainer(STextContainerIndex TextContainerIndex, CTextCursor *pCursor, const char *pText, int Length = -1) = 0;
|
|
// either creates a new text container or appends to a existing one
|
|
virtual bool CreateOrAppendTextContainer(STextContainerIndex &TextContainerIndex, CTextCursor *pCursor, const char *pText, int Length = -1) = 0;
|
|
// just deletes and creates text container
|
|
virtual void RecreateTextContainer(STextContainerIndex &TextContainerIndex, CTextCursor *pCursor, const char *pText, int Length = -1) = 0;
|
|
virtual void RecreateTextContainerSoft(STextContainerIndex &TextContainerIndex, CTextCursor *pCursor, const char *pText, int Length = -1) = 0;
|
|
virtual void DeleteTextContainer(STextContainerIndex &TextContainerIndex) = 0;
|
|
|
|
virtual void UploadTextContainer(STextContainerIndex TextContainerIndex) = 0;
|
|
|
|
virtual void RenderTextContainer(STextContainerIndex TextContainerIndex, const ColorRGBA &TextColor, const ColorRGBA &TextOutlineColor) = 0;
|
|
virtual void RenderTextContainer(STextContainerIndex TextContainerIndex, const ColorRGBA &TextColor, const ColorRGBA &TextOutlineColor, float X, float Y) = 0;
|
|
|
|
virtual STextBoundingBox GetBoundingBoxTextContainer(STextContainerIndex TextContainerIndex) = 0;
|
|
|
|
virtual void UploadEntityLayerText(void *pTexBuff, size_t PixelSize, size_t TexWidth, size_t TexHeight, int TexSubWidth, int TexSubHeight, const char *pText, int Length, float x, float y, int FontSize) = 0;
|
|
virtual int AdjustFontSize(const char *pText, int TextLength, int MaxSize, int MaxWidth) const = 0;
|
|
virtual float GetGlyphOffsetX(int FontSize, char TextCharacter) const = 0;
|
|
virtual int CalculateTextWidth(const char *pText, int TextLength, int FontWidth, int FontSize) const = 0;
|
|
|
|
// old foolish interface
|
|
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 TextSelectionColor(float r, float g, float b, float a) = 0;
|
|
virtual void TextSelectionColor(ColorRGBA rgb) = 0;
|
|
virtual void Text(float x, float y, float Size, const char *pText, float LineWidth = -1.0f) = 0;
|
|
virtual float TextWidth(float Size, const char *pText, int StrLength = -1, float LineWidth = -1.0f, int Flags = 0, const STextSizeProperties &TextSizeProps = {}) = 0;
|
|
virtual STextBoundingBox TextBoundingBox(float Size, const char *pText, int StrLength = -1, float LineWidth = -1.0f, int Flags = 0) = 0;
|
|
|
|
virtual ColorRGBA GetTextColor() const = 0;
|
|
virtual ColorRGBA GetTextOutlineColor() const = 0;
|
|
virtual ColorRGBA GetTextSelectionColor() const = 0;
|
|
|
|
virtual void OnPreWindowResize() = 0;
|
|
virtual void OnWindowResize() = 0;
|
|
};
|
|
|
|
class IEngineTextRender : public ITextRender
|
|
{
|
|
MACRO_INTERFACE("enginetextrender", 0)
|
|
public:
|
|
virtual void Init() = 0;
|
|
virtual void Shutdown() override = 0;
|
|
};
|
|
|
|
extern IEngineTextRender *CreateEngineTextRender();
|
|
|
|
#endif
|