mirror of
https://github.com/ddnet/ddnet.git
synced 2024-09-20 09:34:19 +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));
|
||||
char aBuf[IO_MAX_PATH_LENGTH + 128];
|
||||
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)
|
||||
{
|
||||
|
@ -1043,69 +1047,69 @@ void CMenus::RenderDemoList(CUIRect MainView)
|
|||
int m_Direction;
|
||||
float m_Width;
|
||||
CUIRect m_Rect;
|
||||
CUIRect m_Spacer;
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
COL_DEMONAME = 0,
|
||||
COL_ICON = 0,
|
||||
COL_DEMONAME,
|
||||
COL_MARKERS,
|
||||
COL_LENGTH,
|
||||
COL_DATE,
|
||||
};
|
||||
|
||||
static CListBox s_ListBox;
|
||||
static CColumn s_aCols[] = {
|
||||
{COL_DEMONAME, SORT_DEMONAME, Localizable("Demo"), 0, 0.0f, {0}, {0}},
|
||||
{COL_MARKERS, SORT_MARKERS, Localizable("Markers"), 1, 75.0f, {0}, {0}},
|
||||
{COL_LENGTH, SORT_LENGTH, Localizable("Length"), 1, 75.0f, {0}, {0}},
|
||||
{COL_DATE, SORT_DATE, Localizable("Date"), 1, 160.0f, {0}, {0}},
|
||||
{-1, -1, "", -1, 2.0f, {0}},
|
||||
{COL_ICON, -1, "", -1, ms_ListheaderHeight, {0}},
|
||||
{-1, -1, "", -1, 2.0f, {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);
|
||||
|
||||
int NumCols = std::size(s_aCols);
|
||||
Headers.Draw(ColorRGBA(0.0f, 0.0f, 0.0f, 0.15f), IGraphics::CORNER_NONE, 0.0f);
|
||||
|
||||
// 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);
|
||||
|
||||
if(i + 1 < NumCols)
|
||||
{
|
||||
Headers.VSplitLeft(2, &s_aCols[i].m_Spacer, &Headers);
|
||||
}
|
||||
Headers.VSplitLeft(Col.m_Width, &Col.m_Rect, &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)
|
||||
{
|
||||
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)
|
||||
s_aCols[i].m_Rect = Headers;
|
||||
if(Col.m_Direction == 0)
|
||||
Col.m_Rect = 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;
|
||||
else
|
||||
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
|
||||
|
@ -1114,13 +1118,12 @@ void CMenus::RenderDemoList(CUIRect MainView)
|
|||
}
|
||||
}
|
||||
|
||||
static CListBox s_ListBox;
|
||||
if(m_DemolistSelectedReveal)
|
||||
{
|
||||
s_ListBox.ScrollToSelected();
|
||||
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;
|
||||
for(auto &Item : m_vDemos)
|
||||
|
@ -1131,63 +1134,61 @@ void CMenus::RenderDemoList(CUIRect MainView)
|
|||
if(!ListItem.m_Visible)
|
||||
continue;
|
||||
|
||||
CUIRect Row = ListItem.m_Rect;
|
||||
CUIRect FileIcon;
|
||||
Row.VSplitLeft(Row.h, &FileIcon, &Row);
|
||||
Row.VSplitLeft(5.0f, 0, &Row);
|
||||
FileIcon.Margin(1.0f, &FileIcon);
|
||||
FileIcon.x += 2.0f;
|
||||
|
||||
const char *pIconType;
|
||||
if(Item.m_IsLink || str_comp(Item.m_aFilename, "..") == 0)
|
||||
pIconType = FONT_ICON_FOLDER_TREE;
|
||||
else if(Item.m_IsDir)
|
||||
pIconType = FONT_ICON_FOLDER;
|
||||
else
|
||||
pIconType = FONT_ICON_FILM;
|
||||
|
||||
ColorRGBA IconColor(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
if(!Item.m_IsDir && (!Item.m_InfosLoaded || !Item.m_Valid))
|
||||
IconColor = ColorRGBA(0.6f, 0.6f, 0.6f, 1.0f); // not loaded
|
||||
|
||||
TextRender()->SetCurFont(TextRender()->GetFont(TEXT_FONT_ICON_FONT));
|
||||
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);
|
||||
UI()->DoLabel(&FileIcon, pIconType, 12.0f, TEXTALIGN_ML);
|
||||
TextRender()->SetRenderFlags(0);
|
||||
TextRender()->TextColor(TextRender()->DefaultTextColor());
|
||||
TextRender()->SetCurFont(nullptr);
|
||||
|
||||
for(int c = 0; c < NumCols; c++)
|
||||
for(const auto &Col : s_aCols)
|
||||
{
|
||||
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;
|
||||
Button.x = Col.m_Rect.x;
|
||||
Button.y = ListItem.m_Rect.y;
|
||||
Button.h = ListItem.m_Rect.h;
|
||||
Button.w = Col.m_Rect.w;
|
||||
|
||||
int ID = s_aCols[c].m_ID;
|
||||
int ID = Col.m_ID;
|
||||
|
||||
if(ID == COL_DEMONAME)
|
||||
if(ID == COL_ICON)
|
||||
{
|
||||
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);
|
||||
Button.Margin(1.0f, &Button);
|
||||
|
||||
const char *pIconType;
|
||||
if(Item.m_IsLink || str_comp(Item.m_aFilename, "..") == 0)
|
||||
pIconType = FONT_ICON_FOLDER_TREE;
|
||||
else if(Item.m_IsDir)
|
||||
pIconType = FONT_ICON_FOLDER;
|
||||
else
|
||||
pIconType = FONT_ICON_FILM;
|
||||
|
||||
ColorRGBA IconColor;
|
||||
if(!Item.m_IsDir && (!Item.m_InfosLoaded || !Item.m_Valid))
|
||||
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()->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);
|
||||
UI()->DoLabel(&Button, pIconType, 12.0f, TEXTALIGN_ML);
|
||||
TextRender()->SetRenderFlags(0);
|
||||
TextRender()->TextColor(TextRender()->DefaultTextColor());
|
||||
TextRender()->SetCurFont(nullptr);
|
||||
}
|
||||
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];
|
||||
str_format(aBuf, sizeof(aBuf), "%d", Item.NumMarkers());
|
||||
Button.VMargin(4.0f, &Button);
|
||||
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];
|
||||
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);
|
||||
UI()->DoLabel(&Button, aBuf, 12.0f, TEXTALIGN_MR);
|
||||
}
|
||||
|
@ -1195,7 +1196,7 @@ void CMenus::RenderDemoList(CUIRect MainView)
|
|||
{
|
||||
char aBuf[64];
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue