5503: Improve rendering of demo list icons, remove duplicate code r=Jupeyy a=Robyt3

I first tried adapting and using `CMenus::DoButton_Icon` like `DoIcon` on upstream to reduce duplicate code in the menus. Later I moved/renamed this method to `CRenderTools::RenderIcon`, to also use it in the editor.

Changes to demo list:
- Show the icons as part of the name column
- Improve spacing/centering of icons in columns
- Grey out icon if demo is not loaded or not valid
- Clamp the number of demo markers to valid range (I have an old version 3 demo that incorrectly shows more than a million markers otherwise, which would not fit the char buffer used for rendering the number)

The visual changes are mostly consistent with upstream. Upstream also renders demo icons in green when the demo has markers, but I don't see a good motivation for that especially with a separate markers column already existing.

Before:

![demo old](https://user-images.githubusercontent.com/23437060/175780176-edbd3d98-a257-4982-b590-f32cdb3b1cf3.png)

After:

![demo new](https://user-images.githubusercontent.com/23437060/175780178-64c694b4-d2ae-4b87-8601-47725355454f.png)

Closes #1576. There's likely more duplicate code but I don't think we need this issue open anymore to remind us of that, unless it list more actionable examples of duplicate code that should be refactored.

## Checklist

- [X] Tested the change ingame
- [X] Provided screenshots if it is a visual change
- [ ] Tested in combination with possibly related configuration options
- [ ] Written a unit test if it works standalone, system.c especially
- [ ] Considered possible null pointers and out of bounds array indexing
- [ ] Changed no physics that affect existing maps
- [ ] Tested the change with [ASan+UBSan or valgrind's memcheck](https://github.com/ddnet/ddnet/#using-addresssanitizer--undefinedbehavioursanitizer-or-valgrinds-memcheck) (optional)


Co-authored-by: Robert Müller <robytemueller@gmail.com>
This commit is contained in:
bors[bot] 2022-06-25 16:49:14 +00:00 committed by GitHub
commit fbfd938f32
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 34 additions and 65 deletions

View file

@ -796,7 +796,7 @@ int CDemoPlayer::Load(class IStorage *pStorage, class IConsole *pConsole, const
{
// get timeline markers
int Num = bytes_be_to_int(m_Info.m_TimelineMarkers.m_aNumTimelineMarkers);
m_Info.m_Info.m_NumTimelineMarkers = minimum(Num, (int)MAX_TIMELINE_MARKERS);
m_Info.m_Info.m_NumTimelineMarkers = clamp<int>(Num, 0, MAX_TIMELINE_MARKERS);
for(int i = 0; i < m_Info.m_Info.m_NumTimelineMarkers; i++)
{
m_Info.m_Info.m_aTimelineMarkers[i] = bytes_be_to_int(m_Info.m_TimelineMarkers.m_aTimelineMarkers[i]);

View file

@ -108,36 +108,6 @@ CMenus::CMenus()
}
}
int CMenus::DoButton_Icon(int ImageId, int SpriteId, const CUIRect *pRect)
{
int x = pRect->x;
int y = pRect->y;
int w = pRect->w;
int h = pRect->h;
// Square and center
if(w > h)
{
x += (w - h) / 2;
w = h;
}
else if(h > w)
{
y += (h - w) / 2;
h = w;
}
Graphics()->TextureSet(g_pData->m_aImages[ImageId].m_Id);
Graphics()->QuadsBegin();
RenderTools()->SelectSprite(SpriteId);
IGraphics::CQuadItem QuadItem(x, y, w, h);
Graphics()->QuadsDrawTL(&QuadItem, 1);
Graphics()->QuadsEnd();
return 0;
}
int CMenus::DoButton_Toggle(const void *pID, int Checked, const CUIRect *pRect, bool Active)
{
Graphics()->TextureSet(g_pData->m_aImages[IMAGE_GUIBUTTONS].m_Id);

View file

@ -94,7 +94,6 @@ class CMenus : public CComponent
ColorHSLA DoLine_ColorPicker(int *pResetID, float LineSize, float WantedPickerPosition, float LabelSize, float BottomMargin, CUIRect *pMainRect, const char *pText, unsigned int *pColorValue, ColorRGBA DefaultColor, bool CheckBoxSpacing = true, bool UseCheckBox = false, int *pCheckBoxValue = nullptr);
void DoLaserPreview(const CUIRect *pRect, ColorHSLA OutlineColor, ColorHSLA InnerColor);
int DoValueSelector(void *pID, CUIRect *pRect, const char *pLabel, bool UseScroll, int Current, int Min, int Max, int Step, float Scale, bool IsHex, float Round, ColorRGBA *Color);
int DoButton_Icon(int ImageId, int SpriteId, const CUIRect *pRect);
int DoButton_GridHeader(const void *pID, const char *pText, int Checked, const CUIRect *pRect);
void DoButton_KeySelect(const void *pID, const char *pText, int Checked, const CUIRect *pRect);
@ -386,7 +385,7 @@ protected:
int NumMarkers() const
{
return bytes_be_to_int(m_TimelineMarkers.m_aNumTimelineMarkers);
return clamp<int>(bytes_be_to_int(m_TimelineMarkers.m_aNumTimelineMarkers), 0, MAX_TIMELINE_MARKERS);
}
int Length() const

View file

@ -1003,15 +1003,13 @@ void CMenus::RenderDemoList(CUIRect MainView)
enum
{
COL_ICON = 0,
COL_DEMONAME,
COL_DEMONAME = 0,
COL_MARKERS,
COL_LENGTH,
COL_DATE,
};
static CColumn s_aCols[] = {
{COL_ICON, -1, " ", -1, 14.0f, 0, {0}, {0}},
{COL_DEMONAME, SORT_DEMONAME, "Demo", 0, 0.0f, 0, {0}, {0}},
{COL_MARKERS, SORT_MARKERS, "Markers", 1, 75.0f, 0, {0}, {0}},
{COL_LENGTH, SORT_LENGTH, "Length", 1, 75.0f, 0, {0}, {0}},
@ -1140,6 +1138,18 @@ void CMenus::RenderDemoList(CUIRect MainView)
continue;
}
CUIRect FileIcon;
Row.VSplitLeft(Row.h, &FileIcon, &Row);
Row.VSplitLeft(5.0f, 0, &Row);
FileIcon.Margin(2.0f, &FileIcon);
FileIcon.x += 2.0f;
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
RenderTools()->RenderIcon(IMAGE_FILEICONS, Item.m_IsDir ? SPRITE_FILE_FOLDER : SPRITE_FILE_DEMO1, &FileIcon, &IconColor);
for(int c = 0; c < NumCols; c++)
{
CUIRect Button;
@ -1150,12 +1160,9 @@ void CMenus::RenderDemoList(CUIRect MainView)
int ID = s_aCols[c].m_ID;
if(ID == COL_ICON)
{
DoButton_Icon(IMAGE_FILEICONS, Item.m_IsDir ? SPRITE_FILE_FOLDER : SPRITE_FILE_DEMO1, &Button);
}
else if(ID == COL_DEMONAME)
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;

View file

@ -225,30 +225,15 @@ void CMenus::RenderPlayers(CUIRect MainView)
ButtonBar.HMargin(1.0f, &ButtonBar);
float Width = ButtonBar.h * 2.0f;
ButtonBar.VSplitLeft(Width, &Button, &ButtonBar);
Graphics()->TextureSet(g_pData->m_aImages[IMAGE_GUIICONS].m_Id);
Graphics()->QuadsBegin();
RenderTools()->SelectSprite(SPRITE_GUIICON_MUTE);
IGraphics::CQuadItem QuadItem(Button.x, Button.y, Button.w, Button.h);
Graphics()->QuadsDrawTL(&QuadItem, 1);
Graphics()->QuadsEnd();
RenderTools()->RenderIcon(IMAGE_GUIICONS, SPRITE_GUIICON_MUTE, &Button);
ButtonBar.VSplitLeft(20.0f, 0, &ButtonBar);
ButtonBar.VSplitLeft(Width, &Button, &ButtonBar);
Graphics()->TextureSet(g_pData->m_aImages[IMAGE_GUIICONS].m_Id);
Graphics()->QuadsBegin();
RenderTools()->SelectSprite(SPRITE_GUIICON_EMOTICON_MUTE);
QuadItem = IGraphics::CQuadItem(Button.x, Button.y, Button.w, Button.h);
Graphics()->QuadsDrawTL(&QuadItem, 1);
Graphics()->QuadsEnd();
RenderTools()->RenderIcon(IMAGE_GUIICONS, SPRITE_GUIICON_EMOTICON_MUTE, &Button);
ButtonBar.VSplitLeft(20.0f, 0, &ButtonBar);
ButtonBar.VSplitLeft(Width, &Button, &ButtonBar);
Graphics()->TextureSet(g_pData->m_aImages[IMAGE_GUIICONS].m_Id);
Graphics()->QuadsBegin();
RenderTools()->SelectSprite(SPRITE_GUIICON_FRIEND);
QuadItem = IGraphics::CQuadItem(Button.x, Button.y, Button.w, Button.h);
Graphics()->QuadsDrawTL(&QuadItem, 1);
Graphics()->QuadsEnd();
RenderTools()->RenderIcon(IMAGE_GUIICONS, SPRITE_GUIICON_FRIEND, &Button);
int TotalPlayers = 0;

View file

@ -131,6 +131,18 @@ void CRenderTools::RenderCursor(vec2 Center, float Size)
Graphics()->WrapNormal();
}
void CRenderTools::RenderIcon(int ImageId, int SpriteId, const CUIRect *pRect, const ColorRGBA *pColor)
{
Graphics()->TextureSet(g_pData->m_aImages[ImageId].m_Id);
Graphics()->QuadsBegin();
SelectSprite(SpriteId);
if(pColor)
Graphics()->SetColor(pColor->r * pColor->a, pColor->g * pColor->a, pColor->b * pColor->a, pColor->a);
IGraphics::CQuadItem QuadItem(pRect->x, pRect->y, pRect->w, pRect->h);
Graphics()->QuadsDrawTL(&QuadItem, 1);
Graphics()->QuadsEnd();
}
int CRenderTools::QuadContainerAddSprite(int QuadContainerIndex, float x, float y, float Size)
{
IGraphics::CQuadItem QuadItem(x, y, Size, Size);

View file

@ -92,6 +92,7 @@ public:
void DrawSprite(float x, float y, float size);
void DrawSprite(float x, float y, float ScaledWidth, float ScaledHeight);
void RenderCursor(vec2 Center, float Size);
void RenderIcon(int ImageId, int SpriteId, const CUIRect *pRect, const ColorRGBA *pColor = nullptr);
int QuadContainerAddSprite(int QuadContainerIndex, float x, float y, float size);
int QuadContainerAddSprite(int QuadContainerIndex, float size);
int QuadContainerAddSprite(int QuadContainerIndex, float Width, float Height);

View file

@ -4325,12 +4325,7 @@ void CEditor::AddFileDialogEntry(int Index, CUIRect *pView)
Button.VSplitLeft(Button.h, &FileIcon, &Button);
Button.VSplitLeft(5.0f, nullptr, &Button);
Graphics()->TextureSet(g_pData->m_aImages[IMAGE_FILEICONS].m_Id);
Graphics()->QuadsBegin();
RenderTools()->SelectSprite(m_vFileList[Index].m_IsDir ? SPRITE_FILE_FOLDER : SPRITE_FILE_MAP2);
IGraphics::CQuadItem QuadItem(FileIcon.x, FileIcon.y, FileIcon.w, FileIcon.h);
Graphics()->QuadsDrawTL(&QuadItem, 1);
Graphics()->QuadsEnd();
RenderTools()->RenderIcon(IMAGE_FILEICONS, m_vFileList[Index].m_IsDir ? SPRITE_FILE_FOLDER : SPRITE_FILE_MAP2, &FileIcon);
if(DoButton_File(&m_vFileList[Index], m_vFileList[Index].m_aName, m_FilesSelectedIndex == Index, &Button, 0, nullptr))
{