mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-09-17 11:35:08 -04:00
Port player list widget to C.
This commit is contained in:
parent
9c77405f3c
commit
e4310342bb
@ -41,7 +41,7 @@ namespace ClassicalSharp.Gui.Widgets {
|
||||
SortAndReposition();
|
||||
|
||||
overview = TextWidget.Create(game, "Connected players:", font)
|
||||
.SetLocation(Anchor.Centre, Anchor.LeftOrTop, 0, 0);
|
||||
.SetLocation(Anchor.Centre, Anchor.LeftOrTop, 0, 0);
|
||||
game.EntityEvents.TabListEntryAdded += TabEntryAdded;
|
||||
game.EntityEvents.TabListEntryRemoved += TabEntryRemoved;
|
||||
game.EntityEvents.TabListEntryChanged += TabEntryChanged;
|
||||
@ -273,7 +273,7 @@ namespace ClassicalSharp.Gui.Widgets {
|
||||
void SortEntries() {
|
||||
if (namesCount == 0) return;
|
||||
if (classic) {
|
||||
Array.Sort(IDs, textures, 0, namesCount, grpComparer);
|
||||
Array.Sort(IDs, textures, 0, namesCount, comparer);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -86,7 +86,7 @@ namespace ClassicalSharp.Renderers {
|
||||
v.X = x2; v.Z = z2; v.U = 1; vertices[vCount++] = v;
|
||||
v.Y = y1; v.V = v1; vertices[vCount++] = v;
|
||||
|
||||
v.Z = z1; vertices[vCount++] = v;
|
||||
v.Z = z1; vertices[vCount++] = v;
|
||||
v.Y = y2; v.V = v2; vertices[vCount++] = v;
|
||||
v.X = x1; v.Z = z2; v.U = 0; vertices[vCount++] = v;
|
||||
v.Y = y1; v.V = v1; vertices[vCount++] = v;
|
||||
|
@ -394,8 +394,12 @@ void Entities_DrawShadows(void) {
|
||||
Gfx_SetTexturing(false);
|
||||
}
|
||||
|
||||
bool TabList_Valid(EntityID id) {
|
||||
return TabList_PlayerNames[id] > 0 || TabList_ListNames[id] > 0 || TabList_GroupNames[id] > 0;
|
||||
}
|
||||
|
||||
bool TabList_Remove(EntityID id) {
|
||||
if (TabList_PlayerNames[id] == 0 && TabList_ListNames[id] == 0 && TabList_GroupNames[id] == 0) return false;
|
||||
if (!TabList_Valid(id)) return false;
|
||||
|
||||
StringsBuffer_Remove(&TabList_Buffer, TabList_PlayerNames[id]); TabList_PlayerNames[id] = 0;
|
||||
StringsBuffer_Remove(&TabList_Buffer, TabList_ListNames[id]); TabList_ListNames[id] = 0;
|
||||
|
@ -123,8 +123,12 @@ UInt32 TabList_PlayerNames[TABLIST_MAX_NAMES];
|
||||
UInt32 TabList_ListNames[TABLIST_MAX_NAMES];
|
||||
UInt32 TabList_GroupNames[TABLIST_MAX_NAMES];
|
||||
UInt8 TabList_GroupRanks[TABLIST_MAX_NAMES];
|
||||
bool TabList_Valid(EntityID id);
|
||||
bool TabList_Remove(EntityID id);
|
||||
void TabList_Set(EntityID id, STRING_PURE String* player, STRING_PURE String* list, STRING_PURE String* group, UInt8 rank);
|
||||
IGameComponent TabList_MakeComponent(void);
|
||||
|
||||
#define TabList_UNSAFE_GetPlayer(id) StringsBuffer_UNSAFE_Get(&TabList_Buffer, TabList_PlayerNames[id]);
|
||||
#define TabList_UNSAFE_GetList(id) StringsBuffer_UNSAFE_Get(&TabList_Buffer, TabList_ListNames[id]);
|
||||
#define TabList_UNSAFE_GetGroup(id) StringsBuffer_UNSAFE_Get(&TabList_Buffer, TabList_GroupNames[id]);
|
||||
#endif
|
@ -246,6 +246,19 @@ Int32 String_IndexOfString(STRING_PURE String* str, STRING_PURE String* sub) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
Int32 String_Compare(STRING_PURE String* a, STRING_PURE String* b) {
|
||||
Int32 minLen = min(a->length, b->length);
|
||||
Int32 i;
|
||||
for (i = 0; i < minLen; i++) {
|
||||
if (a->buffer[i] == b->buffer[i]) continue;
|
||||
return a->buffer[i] < b->buffer[i] ? 1 : -1;
|
||||
}
|
||||
|
||||
/* all chars are equal here - same string, or a substring */
|
||||
if (a->length == b->length) return 0;
|
||||
return a->length < b->length ? 1 : -1;
|
||||
}
|
||||
|
||||
|
||||
#define Convert_ControlCharsCount 32
|
||||
UInt16 Convert_ControlChars[Convert_ControlCharsCount] = {
|
||||
|
@ -70,6 +70,7 @@ void String_DeleteAt(STRING_TRANSIENT String* str, Int32 offset);
|
||||
Int32 String_IndexOfString(STRING_PURE String* str, STRING_PURE String* sub);
|
||||
#define String_ContainsString(str, sub) (String_IndexOfString(str, sub) >= 0)
|
||||
#define String_StartsWith(str, sub) (String_IndexOfString(str, sub) == 0)
|
||||
Int32 String_Compare(STRING_PURE String* a, STRING_PURE String* b);
|
||||
|
||||
UInt16 Convert_CP437ToUnicode(UInt8 c);
|
||||
UInt8 Convert_UnicodeToCP437(UInt16 c);
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "Platform.h"
|
||||
#include "WordWrap.h"
|
||||
#include "ServerConnection.h"
|
||||
#include "Event.h"
|
||||
|
||||
void Widget_SetLocation(Widget* widget, Anchor horAnchor, Anchor verAnchor, Int32 xOffset, Int32 yOffset) {
|
||||
widget->HorAnchor = horAnchor; widget->VerAnchor = verAnchor;
|
||||
@ -1533,3 +1534,383 @@ void InputWidget_Create(InputWidget* widget, FontDesc* font, STRING_REF String*
|
||||
widget->PrefixWidth = (UInt16)size.Width; widget->Base.Width = size.Width;
|
||||
widget->PrefixHeight = (UInt16)size.Height; widget->Base.Height = size.Height;
|
||||
}
|
||||
|
||||
|
||||
#define GROUP_NAME_ID UInt16_MaxValue
|
||||
#define LIST_COLUMN_PADDING 5
|
||||
#define LIST_BOUNDS_SIZE 10
|
||||
#define LIST_NAMES_PER_COLUMN 16
|
||||
PackedCol list_topCol = PACKEDCOL_CONST(0, 0, 0, 180);
|
||||
PackedCol list_bottomCol = PACKEDCOL_CONST(50, 50, 50, 205);
|
||||
|
||||
Texture PlayerListWidget_DrawName(PlayerListWidget* widget, STRING_PURE String* name) {
|
||||
UInt8 tmpBuffer[String_BufferSize(STRING_SIZE)];
|
||||
String tmp;
|
||||
if (Game_PureClassic) {
|
||||
tmp = String_InitAndClearArray(tmpBuffer);
|
||||
String_AppendColorless(&tmp, name);
|
||||
} else {
|
||||
tmp = *name;
|
||||
}
|
||||
|
||||
DrawTextArgs args; DrawTextArgs_Make(&args, &tmp, &widget->Font, !widget->Classic);
|
||||
Texture tex = Drawer2D_MakeTextTexture(&args, 0, 0);
|
||||
Drawer2D_ReducePadding_Tex(&tex, widget->Font.Size, 3);
|
||||
return tex;
|
||||
}
|
||||
|
||||
|
||||
Int32 PlayerListWidget_HighlightedName(PlayerListWidget* widget, Int32 mouseX, Int32 mouseY) {
|
||||
Int32 i;
|
||||
for (i = 0; i < widget->NamesCount; i++) {
|
||||
if (!Texture_IsValid(&widget->Textures[i]) || widget->IDs[i] == GROUP_NAME_ID) continue;
|
||||
|
||||
Texture t = widget->Textures[i];
|
||||
if (Gui_Contains(t.X, t.Y, t.Width, t.Height, mouseX, mouseY)) return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void PlayerListWidget_GetNameUnder(PlayerListWidget* widget, Int32 mouseX, Int32 mouseY, STRING_TRANSIENT String* name) {
|
||||
String_Clear(name);
|
||||
Int32 i = PlayerListWidget_HighlightedName(widget, mouseX, mouseY);
|
||||
if (i == -1) return;
|
||||
|
||||
String player = TabList_UNSAFE_GetPlayer(widget->IDs[i]);
|
||||
String_AppendString(name, &player);
|
||||
}
|
||||
|
||||
void PlayerListWidget_UpdateTableDimensions(PlayerListWidget* widget) {
|
||||
Int32 width = widget->XMax - widget->XMin, height = widget->YHeight;
|
||||
widget->Base.X = (widget->XMin ) - LIST_BOUNDS_SIZE;
|
||||
widget->Base.Y = (Game_Height / 2 - height / 2) - LIST_BOUNDS_SIZE;
|
||||
widget->Base.Width = width + LIST_BOUNDS_SIZE * 2;
|
||||
widget->Base.Height = height + LIST_BOUNDS_SIZE * 2;
|
||||
}
|
||||
|
||||
Int32 PlayerListWidget_GetColumnWidth(PlayerListWidget* widget, Int32 column) {
|
||||
Int32 i = column * LIST_NAMES_PER_COLUMN;
|
||||
Int32 maxWidth = 0;
|
||||
Int32 maxIndex = min(widget->NamesCount, i + LIST_NAMES_PER_COLUMN);
|
||||
|
||||
for (; i < maxIndex; i++) {
|
||||
maxWidth = max(maxWidth, widget->Textures[i].Width);
|
||||
}
|
||||
return maxWidth + LIST_COLUMN_PADDING + widget->ElementOffset;
|
||||
}
|
||||
|
||||
Int32 PlayerListWidget_GetColumnHeight(PlayerListWidget* widget, Int32 column) {
|
||||
Int32 i = column * LIST_NAMES_PER_COLUMN;
|
||||
Int32 total = 0;
|
||||
Int32 maxIndex = min(widget->NamesCount, i + LIST_NAMES_PER_COLUMN);
|
||||
|
||||
for (; i < maxIndex; i++) {
|
||||
total += widget->Textures[i].Height + 1;
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
void PlayerListWidget_SetColumnPos(PlayerListWidget* widget, Int32 column, Int32 x, Int32 y) {
|
||||
Int32 i = column * LIST_NAMES_PER_COLUMN;
|
||||
Int32 maxIndex = min(widget->NamesCount, i + LIST_NAMES_PER_COLUMN);
|
||||
|
||||
for (; i < maxIndex; i++) {
|
||||
Texture tex = widget->Textures[i];
|
||||
tex.X = (Int16)x; tex.Y = (Int16)(y - 10);
|
||||
|
||||
y += tex.Height + 1;
|
||||
/* offset player names a bit, compared to group name */
|
||||
if (!widget->Classic && widget->IDs[i] != GROUP_NAME_ID) {
|
||||
tex.X += (Int16)widget->ElementOffset;
|
||||
}
|
||||
widget->Textures[i] = tex;
|
||||
}
|
||||
}
|
||||
|
||||
void PlayerListWidget_RepositionColumns(PlayerListWidget* widget) {
|
||||
Int32 width = 0, centreX = Game_Width / 2;
|
||||
widget->YHeight = 0;
|
||||
|
||||
Int32 col, columns = Math_CeilDiv(widget->NamesCount, LIST_NAMES_PER_COLUMN);
|
||||
for (col = 0; col < columns; col++) {
|
||||
width += PlayerListWidget_GetColumnWidth(widget, col);
|
||||
Int32 colHeight = PlayerListWidget_GetColumnHeight(widget, col);
|
||||
widget->YHeight = nax(colHeight, widget->YHeight);
|
||||
}
|
||||
|
||||
if (width < 480) width = 480;
|
||||
widget->XMin = centreX - width / 2;
|
||||
widget->XMax = centreX + width / 2;
|
||||
|
||||
Int32 x = widget->XMin, y = Game_Height / 2 - widget->YHeight / 2;
|
||||
for (col = 0; col < columns; col++) {
|
||||
PlayerListWidget_SetColumnPos(widget, col, x, y);
|
||||
x += PlayerListWidget_GetColumnWidth(widget, col);
|
||||
}
|
||||
}
|
||||
|
||||
void PlayerListWidget_RecalcYOffset(PlayerListWidget* widget) {
|
||||
Int32 yPosition = Game_Height / 4 - widget->Base.Height / 2;
|
||||
widget->Base.YOffset = -max(0, yPosition);
|
||||
}
|
||||
|
||||
void PlayerListWidget_Reposition(Widget* elem) {
|
||||
Int32 oldX = elem->X, oldY = elem->Y;
|
||||
Widget_DoReposition(elem);
|
||||
PlayerListWidget* widget = (PlayerListWidget*)elem;
|
||||
|
||||
Int32 i;
|
||||
for (i = 0; i < widget->NamesCount; i++) {
|
||||
widget->Textures[i].X += elem->X - oldX;
|
||||
widget->Textures[i].Y += elem->Y - oldY;
|
||||
}
|
||||
}
|
||||
|
||||
void PlayerListWidget_AddName(PlayerListWidget* widget, EntityID id, Int32 index) {
|
||||
/* insert at end of list */
|
||||
if (index == -1) { index = widget->NamesCount; widget->NamesCount++; }
|
||||
|
||||
String name = TabList_UNSAFE_GetList(id);
|
||||
widget->IDs[index] = id;
|
||||
widget->Textures[index] = PlayerListWidget_DrawName(widget, &name);
|
||||
}
|
||||
|
||||
void PlayerListWidget_DeleteAt(PlayerListWidget* widget, Int32 i) {
|
||||
Texture tex = widget->Textures[i];
|
||||
Gfx_DeleteTexture(&tex.ID);
|
||||
|
||||
for (; i < widget->NamesCount - 1; i++) {
|
||||
widget->IDs[i] = widget->IDs[i + 1];
|
||||
widget->Textures[i] = widget->Textures[i + 1];
|
||||
}
|
||||
|
||||
widget->IDs[widget->NamesCount] = 0;
|
||||
widget->Textures[widget->NamesCount] = Texture_MakeInvalid();
|
||||
widget->NamesCount--;
|
||||
}
|
||||
|
||||
void PlayerListWidget_DeleteGroup(PlayerListWidget* widget, Int32* i) {
|
||||
PlayerListWidget_DeleteAt(widget, *i);
|
||||
(*i)--;
|
||||
}
|
||||
|
||||
void PlayerListWidget_AddGroup(PlayerListWidget* widget, UInt16 id, Int32* index) {
|
||||
Int32 i;
|
||||
for (i = Array_NumElements(widget->IDs) - 1; i > (*index); i--) {
|
||||
widget->IDs[i] = widget->IDs[i - 1];
|
||||
widget->Textures[i] = widget->Textures[i - 1];
|
||||
}
|
||||
|
||||
String group = TabList_UNSAFE_GetGroup(id);
|
||||
widget->IDs[*index] = GROUP_NAME_ID;
|
||||
widget->Textures[*index] = PlayerListWidget_DrawName(widget, &group);
|
||||
|
||||
(*index)++;
|
||||
widget->NamesCount++;
|
||||
}
|
||||
|
||||
Int32 PlayerListWidget_GetGroupCount(PlayerListWidget* widget, UInt16 id, Int32 idx) {
|
||||
String group = TabList_UNSAFE_GetGroup(id);
|
||||
Int32 count = 0;
|
||||
|
||||
while (idx < widget->NamesCount) {
|
||||
String curGroup = TabList_UNSAFE_GetGroup(widget->IDs[idx]);
|
||||
if (!String_CaselessEquals(&group, &curGroup)) return count;
|
||||
idx++; count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
Int32 PlayerListWidget_PlayerCompare(UInt16 x, UInt16 y) {
|
||||
UInt8 xRank = TabList_GroupRanks[x];
|
||||
UInt8 yRank = TabList_GroupRanks[y];
|
||||
if (xRank != yRank) return (xRank < yRank ? 1 : -1);
|
||||
|
||||
UInt8 xNameBuffer[String_BufferSize(STRING_SIZE)];
|
||||
String xName = String_InitAndClearArray(xNameBuffer);
|
||||
String xNameRaw = TabList_UNSAFE_GetList(x);
|
||||
String_AppendColorless(&xName, &xNameRaw);
|
||||
|
||||
UInt8 yNameBuffer[String_BufferSize(STRING_SIZE)];
|
||||
String yName = String_InitAndClearArray(yNameBuffer);
|
||||
String yNameRaw = TabList_UNSAFE_GetList(y);
|
||||
String_AppendColorless(&yName, &yNameRaw);
|
||||
|
||||
return String_Compare(&xName, &yName);
|
||||
}
|
||||
|
||||
Int32 PlayerListWidget_GroupCompare(UInt16 x, UInt16 y) {
|
||||
UInt8 xGroupBuffer[String_BufferSize(STRING_SIZE)];
|
||||
String xGroup = String_InitAndClearArray(xGroupBuffer);
|
||||
String xGroupRaw = TabList_UNSAFE_GetGroup(x);
|
||||
String_AppendColorless(&xGroup, &xGroupRaw);
|
||||
|
||||
UInt8 yGroupBuffer[String_BufferSize(STRING_SIZE)];
|
||||
String yGroup = String_InitAndClearArray(yGroupBuffer);
|
||||
String yGroupRaw = TabList_UNSAFE_GetGroup(y);
|
||||
String_AppendColorless(&yGroup, &yGroupRaw);
|
||||
|
||||
return String_Compare(&xGroup, &yGroup);
|
||||
}
|
||||
|
||||
PlayerListWidget* List_SortObj;
|
||||
Int32 (*List_SortCompare)(UInt16 x, UInt16 y);
|
||||
void PlayerListWidget_QuickSort(Int32 left, Int32 right) {
|
||||
Texture* values = List_SortObj->Textures; Texture value;
|
||||
UInt16* keys = List_SortObj->IDs; UInt16 key;
|
||||
while (left < right) {
|
||||
Int32 i = left, j = right;
|
||||
UInt16 pivot = keys[(i + j) / 2];
|
||||
|
||||
/* partition the list */
|
||||
while (i <= j) {
|
||||
while (List_SortCompare(pivot, keys[i]) > 0) i++;
|
||||
while (List_SortCompare(pivot, keys[j]) < 0) j--;
|
||||
QuickSort_Swap_KV_Maybe();
|
||||
}
|
||||
/* recurse into the smaller subset */
|
||||
QuickSort_Recurse(PlayerListWidget_QuickSort)
|
||||
}
|
||||
}
|
||||
|
||||
void PlayerListWidget_SortEntries(PlayerListWidget* widget) {
|
||||
if (widget->NamesCount == 0) return;
|
||||
List_SortObj = widget;
|
||||
if (widget->Classic) {
|
||||
List_SortCompare = PlayerListWidget_PlayerCompare;
|
||||
PlayerListWidget_QuickSort(0, widget->NamesCount - 1);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Sort the list into groups */
|
||||
Int32 i;
|
||||
for (i = 0; i < widget->NamesCount; i++) {
|
||||
if (widget->IDs[i] != GROUP_NAME_ID) continue;
|
||||
PlayerListWidget_DeleteGroup(widget, &i);
|
||||
}
|
||||
List_SortCompare = PlayerListWidget_GroupCompare;
|
||||
PlayerListWidget_QuickSort(0, widget->NamesCount - 1);
|
||||
|
||||
/* Sort the entries in each group */
|
||||
i = 0;
|
||||
List_SortCompare = PlayerListWidget_PlayerCompare;
|
||||
while (i < widget->NamesCount) {
|
||||
UInt16 id = widget->IDs[i];
|
||||
PlayerListWidget_AddGroup(widget, id, &i);
|
||||
Int32 count = PlayerListWidget_GetGroupCount(widget, id, i);
|
||||
PlayerListWidget_QuickSort(i, i + (count - 1));
|
||||
i += count;
|
||||
}
|
||||
}
|
||||
|
||||
void PlayerListWidget_SortAndReposition(PlayerListWidget* widget) {
|
||||
PlayerListWidget_SortEntries(widget);
|
||||
PlayerListWidget_RepositionColumns(widget);
|
||||
PlayerListWidget_UpdateTableDimensions(widget);
|
||||
PlayerListWidget_RecalcYOffset(widget);
|
||||
PlayerListWidget_Reposition(widget);
|
||||
}
|
||||
|
||||
void PlayerListWidget_TabEntryAdded(void* obj, EntityID id) {
|
||||
PlayerListWidget* widget = (PlayerListWidget*)obj;
|
||||
PlayerListWidget_AddName(widget, id, -1);
|
||||
PlayerListWidget_SortAndReposition(widget);
|
||||
}
|
||||
|
||||
void PlayerListWidget_TabEntryChanged(void* obj, EntityID id) {
|
||||
PlayerListWidget* widget = (PlayerListWidget*)obj;
|
||||
Int32 i;
|
||||
for (i = 0; i < widget->NamesCount; i++) {
|
||||
if (widget->IDs[i] != id) continue;
|
||||
|
||||
Texture tex = widget->Textures[i];
|
||||
Gfx_DeleteTexture(&tex.ID);
|
||||
PlayerListWidget_AddName(widget, id, i);
|
||||
PlayerListWidget_SortAndReposition(widget);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void PlayerListWidget_TabEntryRemoved(void* obj, EntityID id) {
|
||||
PlayerListWidget* widget = (PlayerListWidget*)obj;
|
||||
Int32 i;
|
||||
for (i = 0; i < widget->NamesCount; i++) {
|
||||
if (widget->IDs[i] != id) continue;
|
||||
PlayerListWidget_DeleteAt(widget, i);
|
||||
PlayerListWidget_SortAndReposition(widget);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void PlayerListWidget_Init(GuiElement* elem) {
|
||||
PlayerListWidget* widget = (PlayerListWidget*)elem;
|
||||
Int32 id;
|
||||
for (id = 0; id < TABLIST_MAX_NAMES; id++) {
|
||||
if (!TabList_Valid((EntityID)id)) continue;
|
||||
PlayerListWidget_AddName(widget, (EntityID)id, -1);
|
||||
}
|
||||
PlayerListWidget_SortAndReposition(widget);
|
||||
|
||||
String msg = String_FromConst("Connected players:");
|
||||
TextWidget_Create(&widget->Overview, &msg, &widget->Font);
|
||||
Widget_SetLocation(&widget->Overview.Base, ANCHOR_CENTRE, ANCHOR_LEFT_OR_TOP, 0, 0);
|
||||
|
||||
Event_RegisterEntityID(&TabListEvents_Added, widget, PlayerListWidget_TabEntryAdded);
|
||||
Event_RegisterEntityID(&TabListEvents_Changed, widget, PlayerListWidget_TabEntryChanged);
|
||||
Event_RegisterEntityID(&TabListEvents_Removed, widget, PlayerListWidget_TabEntryRemoved);
|
||||
}
|
||||
|
||||
void PlayerListWidget_Render(GuiElement* elem, Real64 delta) {
|
||||
PlayerListWidget* widget = (PlayerListWidget*)elem;
|
||||
Widget* elemW = &widget->Base;
|
||||
TextWidget* overview = &widget->Overview;
|
||||
|
||||
Gfx_SetTexturing(false);
|
||||
Int32 offset = overview->Base.Height + 10;
|
||||
Int32 height = max(300, elemW->Height + overview->Base.Height);
|
||||
GfxCommon_Draw2DGradient(elemW->X, elemW->Y - offset, elemW->Width, elemW->Height, list_topCol, list_bottomCol);
|
||||
|
||||
Gfx_SetTexturing(true);
|
||||
overview->Base.YOffset = elemW->Y - offset + 5;
|
||||
overview->Base.Reposition(&overview->Base);
|
||||
overview->Base.Base.Render(&overview->Base.Base, delta);
|
||||
|
||||
Int32 i, highlightedI = PlayerListWidget_HighlightedName(widget, Mouse_X, Mouse_Y);
|
||||
for (i = 0; i < widget->NamesCount; i++) {
|
||||
if (!Texture_IsValid(&widget->Textures[i])) continue;
|
||||
|
||||
Texture tex = widget->Textures[i];
|
||||
if (i == highlightedI) tex.X += 4;
|
||||
Texture_Render(&tex);
|
||||
}
|
||||
}
|
||||
|
||||
void PlayerListWidget_Free(GuiElement* elem) {
|
||||
PlayerListWidget* widget = (PlayerListWidget*)elem;
|
||||
Int32 i;
|
||||
for (i = 0; i < widget->NamesCount; i++) {
|
||||
Gfx_DeleteTexture(&widget->Textures[i].ID);
|
||||
}
|
||||
|
||||
elem = &widget->Overview.Base.Base;
|
||||
elem->Free(elem);
|
||||
|
||||
Event_UnregisterEntityID(&TabListEvents_Added, widget, PlayerListWidget_TabEntryAdded);
|
||||
Event_UnregisterEntityID(&TabListEvents_Changed, widget, PlayerListWidget_TabEntryChanged);
|
||||
Event_UnregisterEntityID(&TabListEvents_Removed, widget, PlayerListWidget_TabEntryRemoved);
|
||||
}
|
||||
|
||||
void PlayerListWidget_Create(PlayerListWidget* widget, FontDesc* font, bool classic) {
|
||||
Widget_Init(&widget->Base);
|
||||
widget->NamesCount = 0;
|
||||
|
||||
widget->Base.Base.Init = PlayerListWidget_Init;
|
||||
widget->Base.Base.Free = PlayerListWidget_Free;
|
||||
widget->Base.Reposition = PlayerListWidget_Reposition;
|
||||
|
||||
widget->Base.HorAnchor = ANCHOR_CENTRE;
|
||||
widget->Base.VerAnchor = ANCHOR_CENTRE;
|
||||
widget->Font = *font;
|
||||
widget->Classic = classic;
|
||||
widget->ElementOffset = classic ? 0 : 10;
|
||||
}
|
@ -200,10 +200,12 @@ typedef struct PlayerListWidget_ {
|
||||
UInt16 NamesCount, ElementOffset;
|
||||
Int32 XMin, XMax, YHeight;
|
||||
bool Classic;
|
||||
TextWidget Overview;
|
||||
UInt16 IDs[TABLIST_MAX_NAMES * 2];
|
||||
Texture Textures[TABLIST_MAX_NAMES * 2];
|
||||
} PlayerListWidget;
|
||||
|
||||
void PlayerListWidget_Create(PlayerListWidget* widget, FontDesc* font, bool classic);
|
||||
String* PlayerListWidget_GetNameUnder(Int32 mouseX, Int32 mouseY);
|
||||
void PlayerListWidget_RecalcYOffset(void);
|
||||
void PlayerListWidget_GetNameUnder(PlayerListWidget* widget, Int32 mouseX, Int32 mouseY, STRING_TRANSIENT String* name);
|
||||
void PlayerListWidget_RecalcYOffset(PlayerListWidget* widget);
|
||||
#endif
|
Loading…
x
Reference in New Issue
Block a user