mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-10 10:08:18 +00:00
Improve demo browser layout
Use separate columns for icons and spacing like in the server browser. Always show scrollbar for more consistent layout. Show ellipsis if filename is too long, also for the filename shown in the demo player. Hide number of markers and length if the demo is invalid.
This commit is contained in:
parent
9efab4964b
commit
eb79b17308
|
@ -593,7 +593,11 @@ void CMenus::RenderDemoPlayer(CUIRect MainView)
|
||||||
DemoPlayer()->GetDemoName(aDemoName, sizeof(aDemoName));
|
DemoPlayer()->GetDemoName(aDemoName, sizeof(aDemoName));
|
||||||
char aBuf[IO_MAX_PATH_LENGTH + 128];
|
char aBuf[IO_MAX_PATH_LENGTH + 128];
|
||||||
str_format(aBuf, sizeof(aBuf), Localize("Demofile: %s"), aDemoName);
|
str_format(aBuf, sizeof(aBuf), Localize("Demofile: %s"), aDemoName);
|
||||||
UI()->DoLabel(&NameBar, aBuf, Button.h * 0.5f, TEXTALIGN_ML);
|
SLabelProperties Props;
|
||||||
|
Props.m_MaxWidth = NameBar.w;
|
||||||
|
Props.m_EllipsisAtEnd = true;
|
||||||
|
Props.m_EnableWidthCheck = false;
|
||||||
|
UI()->DoLabel(&NameBar, aBuf, Button.h * 0.5f, TEXTALIGN_ML, Props);
|
||||||
|
|
||||||
if(IncreaseDemoSpeed)
|
if(IncreaseDemoSpeed)
|
||||||
{
|
{
|
||||||
|
@ -1043,69 +1047,69 @@ void CMenus::RenderDemoList(CUIRect MainView)
|
||||||
int m_Direction;
|
int m_Direction;
|
||||||
float m_Width;
|
float m_Width;
|
||||||
CUIRect m_Rect;
|
CUIRect m_Rect;
|
||||||
CUIRect m_Spacer;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
COL_DEMONAME = 0,
|
COL_ICON = 0,
|
||||||
|
COL_DEMONAME,
|
||||||
COL_MARKERS,
|
COL_MARKERS,
|
||||||
COL_LENGTH,
|
COL_LENGTH,
|
||||||
COL_DATE,
|
COL_DATE,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static CListBox s_ListBox;
|
||||||
static CColumn s_aCols[] = {
|
static CColumn s_aCols[] = {
|
||||||
{COL_DEMONAME, SORT_DEMONAME, Localizable("Demo"), 0, 0.0f, {0}, {0}},
|
{-1, -1, "", -1, 2.0f, {0}},
|
||||||
{COL_MARKERS, SORT_MARKERS, Localizable("Markers"), 1, 75.0f, {0}, {0}},
|
{COL_ICON, -1, "", -1, ms_ListheaderHeight, {0}},
|
||||||
{COL_LENGTH, SORT_LENGTH, Localizable("Length"), 1, 75.0f, {0}, {0}},
|
{-1, -1, "", -1, 2.0f, {0}},
|
||||||
{COL_DATE, SORT_DATE, Localizable("Date"), 1, 160.0f, {0}, {0}},
|
{COL_DEMONAME, SORT_DEMONAME, Localizable("Demo"), 0, 0.0f, {0}},
|
||||||
|
{-1, -1, "", 1, 2.0f, {0}},
|
||||||
|
{COL_MARKERS, SORT_MARKERS, Localizable("Markers"), 1, 75.0f, {0}},
|
||||||
|
{-1, -1, "", 1, 2.0f, {0}},
|
||||||
|
{COL_LENGTH, SORT_LENGTH, Localizable("Length"), 1, 75.0f, {0}},
|
||||||
|
{-1, -1, "", 1, 2.0f, {0}},
|
||||||
|
{COL_DATE, SORT_DATE, Localizable("Date"), 1, 160.0f, {0}},
|
||||||
|
{-1, -1, "", 1, s_ListBox.ScrollbarWidthMax(), {0}},
|
||||||
};
|
};
|
||||||
|
|
||||||
Headers.Draw(ColorRGBA(0.0f, 0, 0, 0.15f), 0, 0);
|
Headers.Draw(ColorRGBA(0.0f, 0.0f, 0.0f, 0.15f), IGraphics::CORNER_NONE, 0.0f);
|
||||||
|
|
||||||
int NumCols = std::size(s_aCols);
|
|
||||||
|
|
||||||
// do layout
|
// do layout
|
||||||
for(int i = 0; i < NumCols; i++)
|
for(auto &Col : s_aCols)
|
||||||
{
|
{
|
||||||
if(s_aCols[i].m_Direction == -1)
|
if(Col.m_Direction == -1)
|
||||||
{
|
{
|
||||||
Headers.VSplitLeft(s_aCols[i].m_Width, &s_aCols[i].m_Rect, &Headers);
|
Headers.VSplitLeft(Col.m_Width, &Col.m_Rect, &Headers);
|
||||||
|
|
||||||
if(i + 1 < NumCols)
|
|
||||||
{
|
|
||||||
Headers.VSplitLeft(2, &s_aCols[i].m_Spacer, &Headers);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for(int i = NumCols - 1; i >= 0; i--)
|
for(int i = std::size(s_aCols) - 1; i >= 0; i--)
|
||||||
{
|
{
|
||||||
if(s_aCols[i].m_Direction == 1)
|
if(s_aCols[i].m_Direction == 1)
|
||||||
{
|
{
|
||||||
Headers.VSplitRight(s_aCols[i].m_Width, &Headers, &s_aCols[i].m_Rect);
|
Headers.VSplitRight(s_aCols[i].m_Width, &Headers, &s_aCols[i].m_Rect);
|
||||||
Headers.VSplitRight(2, &Headers, &s_aCols[i].m_Spacer);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for(int i = 0; i < NumCols; i++)
|
for(auto &Col : s_aCols)
|
||||||
{
|
{
|
||||||
if(s_aCols[i].m_Direction == 0)
|
if(Col.m_Direction == 0)
|
||||||
s_aCols[i].m_Rect = Headers;
|
Col.m_Rect = Headers;
|
||||||
}
|
}
|
||||||
|
|
||||||
// do headers
|
// do headers
|
||||||
for(int i = 0; i < NumCols; i++)
|
for(auto &Col : s_aCols)
|
||||||
{
|
{
|
||||||
if(DoButton_GridHeader(s_aCols[i].m_Caption, Localize(s_aCols[i].m_Caption), g_Config.m_BrDemoSort == s_aCols[i].m_Sort, &s_aCols[i].m_Rect))
|
if(DoButton_GridHeader(&Col.m_ID, Col.m_Caption, g_Config.m_BrDemoSort == Col.m_Sort, &Col.m_Rect))
|
||||||
{
|
{
|
||||||
if(s_aCols[i].m_Sort != -1)
|
if(Col.m_Sort != -1)
|
||||||
{
|
{
|
||||||
if(g_Config.m_BrDemoSort == s_aCols[i].m_Sort)
|
if(g_Config.m_BrDemoSort == Col.m_Sort)
|
||||||
g_Config.m_BrDemoSortOrder ^= 1;
|
g_Config.m_BrDemoSortOrder ^= 1;
|
||||||
else
|
else
|
||||||
g_Config.m_BrDemoSortOrder = 0;
|
g_Config.m_BrDemoSortOrder = 0;
|
||||||
g_Config.m_BrDemoSort = s_aCols[i].m_Sort;
|
g_Config.m_BrDemoSort = Col.m_Sort;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Don't rescan in order to keep fetched headers, just resort
|
// Don't rescan in order to keep fetched headers, just resort
|
||||||
|
@ -1114,13 +1118,12 @@ void CMenus::RenderDemoList(CUIRect MainView)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static CListBox s_ListBox;
|
|
||||||
if(m_DemolistSelectedReveal)
|
if(m_DemolistSelectedReveal)
|
||||||
{
|
{
|
||||||
s_ListBox.ScrollToSelected();
|
s_ListBox.ScrollToSelected();
|
||||||
m_DemolistSelectedReveal = false;
|
m_DemolistSelectedReveal = false;
|
||||||
}
|
}
|
||||||
s_ListBox.DoStart(ms_ListheaderHeight, m_vDemos.size(), 1, 3, m_DemolistSelectedIndex, &ListBox, false);
|
s_ListBox.DoStart(ms_ListheaderHeight, m_vDemos.size(), 1, 3, m_DemolistSelectedIndex, &ListBox, false, IGraphics::CORNER_ALL, true);
|
||||||
|
|
||||||
int ItemIndex = -1;
|
int ItemIndex = -1;
|
||||||
for(auto &Item : m_vDemos)
|
for(auto &Item : m_vDemos)
|
||||||
|
@ -1131,12 +1134,19 @@ void CMenus::RenderDemoList(CUIRect MainView)
|
||||||
if(!ListItem.m_Visible)
|
if(!ListItem.m_Visible)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
CUIRect Row = ListItem.m_Rect;
|
for(const auto &Col : s_aCols)
|
||||||
CUIRect FileIcon;
|
{
|
||||||
Row.VSplitLeft(Row.h, &FileIcon, &Row);
|
CUIRect Button;
|
||||||
Row.VSplitLeft(5.0f, 0, &Row);
|
Button.x = Col.m_Rect.x;
|
||||||
FileIcon.Margin(1.0f, &FileIcon);
|
Button.y = ListItem.m_Rect.y;
|
||||||
FileIcon.x += 2.0f;
|
Button.h = ListItem.m_Rect.h;
|
||||||
|
Button.w = Col.m_Rect.w;
|
||||||
|
|
||||||
|
int ID = Col.m_ID;
|
||||||
|
|
||||||
|
if(ID == COL_ICON)
|
||||||
|
{
|
||||||
|
Button.Margin(1.0f, &Button);
|
||||||
|
|
||||||
const char *pIconType;
|
const char *pIconType;
|
||||||
if(Item.m_IsLink || str_comp(Item.m_aFilename, "..") == 0)
|
if(Item.m_IsLink || str_comp(Item.m_aFilename, "..") == 0)
|
||||||
|
@ -1146,48 +1156,39 @@ void CMenus::RenderDemoList(CUIRect MainView)
|
||||||
else
|
else
|
||||||
pIconType = FONT_ICON_FILM;
|
pIconType = FONT_ICON_FILM;
|
||||||
|
|
||||||
ColorRGBA IconColor(1.0f, 1.0f, 1.0f, 1.0f);
|
ColorRGBA IconColor;
|
||||||
if(!Item.m_IsDir && (!Item.m_InfosLoaded || !Item.m_Valid))
|
if(!Item.m_IsDir && (!Item.m_InfosLoaded || !Item.m_Valid))
|
||||||
IconColor = ColorRGBA(0.6f, 0.6f, 0.6f, 1.0f); // not loaded
|
IconColor = ColorRGBA(0.6f, 0.6f, 0.6f, 1.0f); // not loaded
|
||||||
|
else
|
||||||
|
IconColor = ColorRGBA(1.0f, 1.0f, 1.0f, 1.0f);
|
||||||
|
|
||||||
TextRender()->SetCurFont(TextRender()->GetFont(TEXT_FONT_ICON_FONT));
|
TextRender()->SetCurFont(TextRender()->GetFont(TEXT_FONT_ICON_FONT));
|
||||||
TextRender()->TextColor(IconColor);
|
TextRender()->TextColor(IconColor);
|
||||||
TextRender()->SetRenderFlags(ETextRenderFlags::TEXT_RENDER_FLAG_ONLY_ADVANCE_WIDTH | ETextRenderFlags::TEXT_RENDER_FLAG_NO_X_BEARING | ETextRenderFlags::TEXT_RENDER_FLAG_NO_Y_BEARING);
|
TextRender()->SetRenderFlags(ETextRenderFlags::TEXT_RENDER_FLAG_ONLY_ADVANCE_WIDTH | ETextRenderFlags::TEXT_RENDER_FLAG_NO_X_BEARING | ETextRenderFlags::TEXT_RENDER_FLAG_NO_Y_BEARING);
|
||||||
UI()->DoLabel(&FileIcon, pIconType, 12.0f, TEXTALIGN_ML);
|
UI()->DoLabel(&Button, pIconType, 12.0f, TEXTALIGN_ML);
|
||||||
TextRender()->SetRenderFlags(0);
|
TextRender()->SetRenderFlags(0);
|
||||||
TextRender()->TextColor(TextRender()->DefaultTextColor());
|
TextRender()->TextColor(TextRender()->DefaultTextColor());
|
||||||
TextRender()->SetCurFont(nullptr);
|
TextRender()->SetCurFont(nullptr);
|
||||||
|
|
||||||
for(int c = 0; c < NumCols; c++)
|
|
||||||
{
|
|
||||||
CUIRect Button;
|
|
||||||
Button.x = s_aCols[c].m_Rect.x;
|
|
||||||
Button.y = Row.y;
|
|
||||||
Button.h = Row.h;
|
|
||||||
Button.w = s_aCols[c].m_Rect.w;
|
|
||||||
|
|
||||||
int ID = s_aCols[c].m_ID;
|
|
||||||
|
|
||||||
if(ID == COL_DEMONAME)
|
|
||||||
{
|
|
||||||
Button.x += FileIcon.w + 6.0f;
|
|
||||||
CTextCursor Cursor;
|
|
||||||
TextRender()->SetCursor(&Cursor, Button.x, Button.y + (Button.h - 12.0f) / 2.f, 12.0f, TEXTFLAG_RENDER | TEXTFLAG_STOP_AT_END);
|
|
||||||
Cursor.m_LineWidth = Button.w;
|
|
||||||
TextRender()->TextEx(&Cursor, Item.m_aName, -1);
|
|
||||||
}
|
}
|
||||||
else if(ID == COL_MARKERS && !Item.m_IsDir && Item.m_InfosLoaded)
|
else if(ID == COL_DEMONAME)
|
||||||
|
{
|
||||||
|
SLabelProperties Props;
|
||||||
|
Props.m_MaxWidth = Button.w;
|
||||||
|
Props.m_EllipsisAtEnd = true;
|
||||||
|
Props.m_EnableWidthCheck = false;
|
||||||
|
UI()->DoLabel(&Button, Item.m_aName, 12.0f, TEXTALIGN_ML, Props);
|
||||||
|
}
|
||||||
|
else if(ID == COL_MARKERS && !Item.m_IsDir && Item.m_InfosLoaded && Item.m_Valid)
|
||||||
{
|
{
|
||||||
char aBuf[3];
|
char aBuf[3];
|
||||||
str_format(aBuf, sizeof(aBuf), "%d", Item.NumMarkers());
|
str_format(aBuf, sizeof(aBuf), "%d", Item.NumMarkers());
|
||||||
Button.VMargin(4.0f, &Button);
|
Button.VMargin(4.0f, &Button);
|
||||||
UI()->DoLabel(&Button, aBuf, 12.0f, TEXTALIGN_MR);
|
UI()->DoLabel(&Button, aBuf, 12.0f, TEXTALIGN_MR);
|
||||||
}
|
}
|
||||||
else if(ID == COL_LENGTH && !Item.m_IsDir && Item.m_InfosLoaded)
|
else if(ID == COL_LENGTH && !Item.m_IsDir && Item.m_InfosLoaded && Item.m_Valid)
|
||||||
{
|
{
|
||||||
int Length = Item.Length();
|
|
||||||
char aBuf[32];
|
char aBuf[32];
|
||||||
str_time((int64_t)Length * 100, TIME_HOURS, aBuf, sizeof(aBuf));
|
str_time((int64_t)Item.Length() * 100, TIME_HOURS, aBuf, sizeof(aBuf));
|
||||||
Button.VMargin(4.0f, &Button);
|
Button.VMargin(4.0f, &Button);
|
||||||
UI()->DoLabel(&Button, aBuf, 12.0f, TEXTALIGN_MR);
|
UI()->DoLabel(&Button, aBuf, 12.0f, TEXTALIGN_MR);
|
||||||
}
|
}
|
||||||
|
@ -1195,7 +1196,7 @@ void CMenus::RenderDemoList(CUIRect MainView)
|
||||||
{
|
{
|
||||||
char aBuf[64];
|
char aBuf[64];
|
||||||
str_timestamp_ex(Item.m_Date, aBuf, sizeof(aBuf), FORMAT_SPACE);
|
str_timestamp_ex(Item.m_Date, aBuf, sizeof(aBuf), FORMAT_SPACE);
|
||||||
Button.VSplitRight(24.0f, &Button, 0);
|
Button.VMargin(4.0f, &Button);
|
||||||
UI()->DoLabel(&Button, aBuf, 12.0f, TEXTALIGN_MR);
|
UI()->DoLabel(&Button, aBuf, 12.0f, TEXTALIGN_MR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue