mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-10 01:58:19 +00:00
Merge branch 'ddnet:master' into master
This commit is contained in:
commit
9101a4f5ce
|
@ -2103,6 +2103,8 @@ if(CLIENT)
|
||||||
ui.h
|
ui.h
|
||||||
ui_rect.cpp
|
ui_rect.cpp
|
||||||
ui_rect.h
|
ui_rect.h
|
||||||
|
ui_scrollregion.cpp
|
||||||
|
ui_scrollregion.h
|
||||||
)
|
)
|
||||||
set_src(GAME_EDITOR GLOB src/game/editor
|
set_src(GAME_EDITOR GLOB src/game/editor
|
||||||
auto_map.cpp
|
auto_map.cpp
|
||||||
|
|
|
@ -2997,6 +2997,18 @@ const char *str_rchr(const char *haystack, char needle)
|
||||||
return strrchr(haystack, needle);
|
return strrchr(haystack, needle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int str_countchr(const char *haystack, char needle)
|
||||||
|
{
|
||||||
|
int count = 0;
|
||||||
|
while(*haystack)
|
||||||
|
{
|
||||||
|
if(*haystack == needle)
|
||||||
|
count++;
|
||||||
|
haystack++;
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
void str_hex(char *dst, int dst_size, const void *data, int data_size)
|
void str_hex(char *dst, int dst_size, const void *data, int data_size)
|
||||||
{
|
{
|
||||||
static const char hex[] = "0123456789ABCDEF";
|
static const char hex[] = "0123456789ABCDEF";
|
||||||
|
|
|
@ -1588,6 +1588,23 @@ const char *str_find(const char *haystack, const char *needle);
|
||||||
*/
|
*/
|
||||||
const char *str_rchr(const char *haystack, char needle);
|
const char *str_rchr(const char *haystack, char needle);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function: str_countchr
|
||||||
|
Counts the number of occurrences of a character in a string.
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
haystack - String to count in
|
||||||
|
needle - Character to count
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
The number of characters in the haystack string matching
|
||||||
|
the needle character.
|
||||||
|
|
||||||
|
Remarks:
|
||||||
|
- The strings are treated as zero-terminated strings.
|
||||||
|
*/
|
||||||
|
int str_countchr(const char *haystack, char needle);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Function: str_hex
|
Function: str_hex
|
||||||
Takes a datablock and generates a hex string of it, with spaces
|
Takes a datablock and generates a hex string of it, with spaces
|
||||||
|
|
|
@ -324,7 +324,6 @@ MACRO_CONFIG_INT(ClShowOthers, cl_show_others, 0, 0, 2, CFGFLAG_CLIENT | CFGFLAG
|
||||||
MACRO_CONFIG_INT(ClShowOthersAlpha, cl_show_others_alpha, 40, 0, 100, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Show players in other teams (alpha value, 0 invisible, 100 fully visible)")
|
MACRO_CONFIG_INT(ClShowOthersAlpha, cl_show_others_alpha, 40, 0, 100, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Show players in other teams (alpha value, 0 invisible, 100 fully visible)")
|
||||||
MACRO_CONFIG_INT(ClOverlayEntities, cl_overlay_entities, 0, 0, 100, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Overlay game tiles with a percentage of opacity")
|
MACRO_CONFIG_INT(ClOverlayEntities, cl_overlay_entities, 0, 0, 100, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Overlay game tiles with a percentage of opacity")
|
||||||
MACRO_CONFIG_INT(ClShowQuads, cl_showquads, 1, 0, 1, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Show quads (only interesting for mappers, or if your system has extremely bad performance)")
|
MACRO_CONFIG_INT(ClShowQuads, cl_showquads, 1, 0, 1, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Show quads (only interesting for mappers, or if your system has extremely bad performance)")
|
||||||
MACRO_CONFIG_INT(ClZoomBackgroundLayers, cl_zoom_background_layers, 0, 0, 1, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Zoom background layers")
|
|
||||||
MACRO_CONFIG_COL(ClBackgroundColor, cl_background_color, 128, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Background color") // 0 0 128
|
MACRO_CONFIG_COL(ClBackgroundColor, cl_background_color, 128, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Background color") // 0 0 128
|
||||||
MACRO_CONFIG_COL(ClBackgroundEntitiesColor, cl_background_entities_color, 128, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Background (entities) color") // 0 0 128
|
MACRO_CONFIG_COL(ClBackgroundEntitiesColor, cl_background_entities_color, 128, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Background (entities) color") // 0 0 128
|
||||||
MACRO_CONFIG_STR(ClBackgroundEntities, cl_background_entities, 100, "", CFGFLAG_CLIENT | CFGFLAG_SAVE, "Background (entities)")
|
MACRO_CONFIG_STR(ClBackgroundEntities, cl_background_entities, 100, "", CFGFLAG_CLIENT | CFGFLAG_SAVE, "Background (entities)")
|
||||||
|
|
|
@ -621,7 +621,7 @@ void CHud::RenderCursor()
|
||||||
if(!m_pClient->m_Snap.m_pLocalCharacter || Client()->State() == IClient::STATE_DEMOPLAYBACK)
|
if(!m_pClient->m_Snap.m_pLocalCharacter || Client()->State() == IClient::STATE_DEMOPLAYBACK)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
RenderTools()->MapScreenToGroup(m_pClient->m_Camera.m_Center.x, m_pClient->m_Camera.m_Center.y, Layers()->GameGroup());
|
RenderTools()->MapScreenToInterface(m_pClient->m_Camera.m_Center.x, m_pClient->m_Camera.m_Center.y);
|
||||||
|
|
||||||
// render cursor
|
// render cursor
|
||||||
int CurWeapon = m_pClient->m_Snap.m_pLocalCharacter->m_Weapon % NUM_WEAPONS;
|
int CurWeapon = m_pClient->m_Snap.m_pLocalCharacter->m_Weapon % NUM_WEAPONS;
|
||||||
|
|
|
@ -1562,6 +1562,7 @@ void CMapLayers::OnRender()
|
||||||
for(int g = 0; g < m_pLayers->NumGroups(); g++)
|
for(int g = 0; g < m_pLayers->NumGroups(); g++)
|
||||||
{
|
{
|
||||||
CMapItemGroup *pGroup = m_pLayers->GetGroup(g);
|
CMapItemGroup *pGroup = m_pLayers->GetGroup(g);
|
||||||
|
CMapItemGroupEx *pGroupEx = m_pLayers->GetGroupEx(g);
|
||||||
|
|
||||||
if(!pGroup)
|
if(!pGroup)
|
||||||
{
|
{
|
||||||
|
@ -1575,7 +1576,7 @@ void CMapLayers::OnRender()
|
||||||
{
|
{
|
||||||
// set clipping
|
// set clipping
|
||||||
float aPoints[4];
|
float aPoints[4];
|
||||||
RenderTools()->MapScreenToGroup(Center.x, Center.y, m_pLayers->GameGroup(), GetCurCamera()->m_Zoom);
|
RenderTools()->MapScreenToGroup(Center.x, Center.y, m_pLayers->GameGroup(), m_pLayers->GameGroupEx(), GetCurCamera()->m_Zoom);
|
||||||
Graphics()->GetScreen(&aPoints[0], &aPoints[1], &aPoints[2], &aPoints[3]);
|
Graphics()->GetScreen(&aPoints[0], &aPoints[1], &aPoints[2], &aPoints[3]);
|
||||||
float x0 = (pGroup->m_ClipX - aPoints[0]) / (aPoints[2] - aPoints[0]);
|
float x0 = (pGroup->m_ClipX - aPoints[0]) / (aPoints[2] - aPoints[0]);
|
||||||
float y0 = (pGroup->m_ClipY - aPoints[1]) / (aPoints[3] - aPoints[1]);
|
float y0 = (pGroup->m_ClipY - aPoints[1]) / (aPoints[3] - aPoints[1]);
|
||||||
|
@ -1593,12 +1594,7 @@ void CMapLayers::OnRender()
|
||||||
(int)((x1 - x0) * Graphics()->ScreenWidth()), (int)((y1 - y0) * Graphics()->ScreenHeight()));
|
(int)((x1 - x0) * Graphics()->ScreenWidth()), (int)((y1 - y0) * Graphics()->ScreenHeight()));
|
||||||
}
|
}
|
||||||
|
|
||||||
if((!g_Config.m_ClZoomBackgroundLayers || m_Type == TYPE_FULL_DESIGN) && !pGroup->m_ParallaxX && !pGroup->m_ParallaxY)
|
RenderTools()->MapScreenToGroup(Center.x, Center.y, pGroup, pGroupEx, GetCurCamera()->m_Zoom);
|
||||||
{
|
|
||||||
RenderTools()->MapScreenToGroup(Center.x, Center.y, pGroup, 1.0f);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
RenderTools()->MapScreenToGroup(Center.x, Center.y, pGroup, GetCurCamera()->m_Zoom);
|
|
||||||
|
|
||||||
for(int l = 0; l < pGroup->m_NumLayers; l++)
|
for(int l = 0; l < pGroup->m_NumLayers; l++)
|
||||||
{
|
{
|
||||||
|
|
|
@ -113,14 +113,14 @@ class CMenus : public CComponent
|
||||||
Text.HMargin(pRect->h >= 20.0f ? 2.0f : 1.0f, &Text);
|
Text.HMargin(pRect->h >= 20.0f ? 2.0f : 1.0f, &Text);
|
||||||
Text.HMargin((Text.h * FontFactor) / 2.0f, &Text);
|
Text.HMargin((Text.h * FontFactor) / 2.0f, &Text);
|
||||||
|
|
||||||
if(!UIElement.AreRectsInit() || HintRequiresStringCheck || HintCanChangePositionOrSize || UIElement.Get(0)->m_UITextContainer == -1)
|
if(!UIElement.AreRectsInit() || HintRequiresStringCheck || HintCanChangePositionOrSize || UIElement.Rect(0)->m_UITextContainer == -1)
|
||||||
{
|
{
|
||||||
bool NeedsRecalc = !UIElement.AreRectsInit() || UIElement.Get(0)->m_UITextContainer == -1;
|
bool NeedsRecalc = !UIElement.AreRectsInit() || UIElement.Rect(0)->m_UITextContainer == -1;
|
||||||
if(HintCanChangePositionOrSize)
|
if(HintCanChangePositionOrSize)
|
||||||
{
|
{
|
||||||
if(UIElement.AreRectsInit())
|
if(UIElement.AreRectsInit())
|
||||||
{
|
{
|
||||||
if(UIElement.Get(0)->m_X != pRect->x || UIElement.Get(0)->m_Y != pRect->y || UIElement.Get(0)->m_Width != pRect->w || UIElement.Get(0)->m_Y != pRect->h)
|
if(UIElement.Rect(0)->m_X != pRect->x || UIElement.Rect(0)->m_Y != pRect->y || UIElement.Rect(0)->m_Width != pRect->w || UIElement.Rect(0)->m_Y != pRect->h)
|
||||||
{
|
{
|
||||||
NeedsRecalc = true;
|
NeedsRecalc = true;
|
||||||
}
|
}
|
||||||
|
@ -132,7 +132,7 @@ class CMenus : public CComponent
|
||||||
if(UIElement.AreRectsInit())
|
if(UIElement.AreRectsInit())
|
||||||
{
|
{
|
||||||
pText = GetTextLambda();
|
pText = GetTextLambda();
|
||||||
if(str_comp(UIElement.Get(0)->m_Text.c_str(), pText) != 0)
|
if(str_comp(UIElement.Rect(0)->m_Text.c_str(), pText) != 0)
|
||||||
{
|
{
|
||||||
NeedsRecalc = true;
|
NeedsRecalc = true;
|
||||||
}
|
}
|
||||||
|
@ -158,7 +158,7 @@ class CMenus : public CComponent
|
||||||
Color.a *= UI()->ButtonColorMulDefault();
|
Color.a *= UI()->ButtonColorMulDefault();
|
||||||
Graphics()->SetColor(Color);
|
Graphics()->SetColor(Color);
|
||||||
|
|
||||||
CUIElement::SUIElementRect &NewRect = *UIElement.Get(i);
|
CUIElement::SUIElementRect &NewRect = *UIElement.Rect(i);
|
||||||
NewRect.m_UIRectQuadContainer = Graphics()->CreateRectQuadContainer(pRect->x, pRect->y, pRect->w, pRect->h, r, Corners);
|
NewRect.m_UIRectQuadContainer = Graphics()->CreateRectQuadContainer(pRect->x, pRect->y, pRect->w, pRect->h, r, Corners);
|
||||||
|
|
||||||
NewRect.m_X = pRect->x;
|
NewRect.m_X = pRect->x;
|
||||||
|
@ -185,11 +185,11 @@ class CMenus : public CComponent
|
||||||
else if(UI()->HotItem() == pID)
|
else if(UI()->HotItem() == pID)
|
||||||
Index = 1;
|
Index = 1;
|
||||||
Graphics()->TextureClear();
|
Graphics()->TextureClear();
|
||||||
Graphics()->RenderQuadContainer(UIElement.Get(Index)->m_UIRectQuadContainer, -1);
|
Graphics()->RenderQuadContainer(UIElement.Rect(Index)->m_UIRectQuadContainer, -1);
|
||||||
ColorRGBA ColorText(TextRender()->DefaultTextColor());
|
ColorRGBA ColorText(TextRender()->DefaultTextColor());
|
||||||
ColorRGBA ColorTextOutline(TextRender()->DefaultTextOutlineColor());
|
ColorRGBA ColorTextOutline(TextRender()->DefaultTextOutlineColor());
|
||||||
if(UIElement.Get(0)->m_UITextContainer != -1)
|
if(UIElement.Rect(0)->m_UITextContainer != -1)
|
||||||
TextRender()->RenderTextContainer(UIElement.Get(0)->m_UITextContainer, ColorText, ColorTextOutline);
|
TextRender()->RenderTextContainer(UIElement.Rect(0)->m_UITextContainer, ColorText, ColorTextOutline);
|
||||||
return UI()->DoButtonLogic(pID, Checked, pRect);
|
return UI()->DoButtonLogic(pID, Checked, pRect);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -286,13 +286,13 @@ void CMenus::RenderServerbrowserServerList(CUIRect View)
|
||||||
{
|
{
|
||||||
CUIRect r = Row;
|
CUIRect r = Row;
|
||||||
r.Margin(0.5f, &r);
|
r.Margin(0.5f, &r);
|
||||||
pItem->m_pUIElement->Get(0)->Draw(&r, ColorRGBA(1, 1, 1, 0.5f), IGraphics::CORNER_ALL, 4.0f);
|
pItem->m_pUIElement->Rect(0)->Draw(&r, ColorRGBA(1, 1, 1, 0.5f), IGraphics::CORNER_ALL, 4.0f);
|
||||||
}
|
}
|
||||||
else if(UI()->MouseHovered(&Row))
|
else if(UI()->MouseHovered(&Row))
|
||||||
{
|
{
|
||||||
CUIRect r = Row;
|
CUIRect r = Row;
|
||||||
r.Margin(0.5f, &r);
|
r.Margin(0.5f, &r);
|
||||||
pItem->m_pUIElement->Get(0)->Draw(&r, ColorRGBA(1, 1, 1, 0.25f), IGraphics::CORNER_ALL, 4.0f);
|
pItem->m_pUIElement->Rect(0)->Draw(&r, ColorRGBA(1, 1, 1, 0.25f), IGraphics::CORNER_ALL, 4.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(UI()->DoButtonLogic(pItem, Selected, &Row))
|
if(UI()->DoButtonLogic(pItem, Selected, &Row))
|
||||||
|
@ -328,22 +328,22 @@ void CMenus::RenderServerbrowserServerList(CUIRect View)
|
||||||
{
|
{
|
||||||
if(pItem->m_Flags & SERVER_FLAG_PASSWORD)
|
if(pItem->m_Flags & SERVER_FLAG_PASSWORD)
|
||||||
{
|
{
|
||||||
RenderBrowserIcons(*pItem->m_pUIElement->Get(gs_OffsetColFlagLock + 0), &Button, {0.75f, 0.75f, 0.75f, 1}, TextRender()->DefaultTextOutlineColor(), "\xEF\x80\xA3", TEXTALIGN_CENTER);
|
RenderBrowserIcons(*pItem->m_pUIElement->Rect(gs_OffsetColFlagLock + 0), &Button, {0.75f, 0.75f, 0.75f, 1}, TextRender()->DefaultTextOutlineColor(), "\xEF\x80\xA3", TEXTALIGN_CENTER);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(ID == COL_FLAG_FAV)
|
else if(ID == COL_FLAG_FAV)
|
||||||
{
|
{
|
||||||
if(pItem->m_Favorite != TRISTATE::NONE)
|
if(pItem->m_Favorite != TRISTATE::NONE)
|
||||||
{
|
{
|
||||||
RenderBrowserIcons(*pItem->m_pUIElement->Get(gs_OffsetColFav + 0), &Button, {0.94f, 0.4f, 0.4f, 1}, TextRender()->DefaultTextOutlineColor(), "\xEF\x80\x84", TEXTALIGN_CENTER);
|
RenderBrowserIcons(*pItem->m_pUIElement->Rect(gs_OffsetColFav + 0), &Button, {0.94f, 0.4f, 0.4f, 1}, TextRender()->DefaultTextOutlineColor(), "\xEF\x80\x84", TEXTALIGN_CENTER);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(ID == COL_FLAG_OFFICIAL)
|
else if(ID == COL_FLAG_OFFICIAL)
|
||||||
{
|
{
|
||||||
if(pItem->m_Official && g_Config.m_UiPage != PAGE_DDNET && g_Config.m_UiPage != PAGE_KOG)
|
if(pItem->m_Official && g_Config.m_UiPage != PAGE_DDNET && g_Config.m_UiPage != PAGE_KOG)
|
||||||
{
|
{
|
||||||
RenderBrowserIcons(*pItem->m_pUIElement->Get(gs_OffsetColOff + 0), &Button, {0.4f, 0.7f, 0.94f, 1}, {0.0f, 0.0f, 0.0f, 1.0f}, "\xEF\x82\xA3", TEXTALIGN_CENTER);
|
RenderBrowserIcons(*pItem->m_pUIElement->Rect(gs_OffsetColOff + 0), &Button, {0.4f, 0.7f, 0.94f, 1}, {0.0f, 0.0f, 0.0f, 1.0f}, "\xEF\x82\xA3", TEXTALIGN_CENTER);
|
||||||
RenderBrowserIcons(*pItem->m_pUIElement->Get(gs_OffsetColOff + 1), &Button, {0.0f, 0.0f, 0.0f, 1.0f}, {0.0f, 0.0f, 0.0f, 0.0f}, "\xEF\x80\x8C", TEXTALIGN_CENTER, true);
|
RenderBrowserIcons(*pItem->m_pUIElement->Rect(gs_OffsetColOff + 1), &Button, {0.0f, 0.0f, 0.0f, 1.0f}, {0.0f, 0.0f, 0.0f, 0.0f}, "\xEF\x80\x8C", TEXTALIGN_CENTER, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(ID == COL_NAME)
|
else if(ID == COL_NAME)
|
||||||
|
@ -356,17 +356,17 @@ void CMenus::RenderServerbrowserServerList(CUIRect View)
|
||||||
const char *pStr = str_utf8_find_nocase(pItem->m_aName, g_Config.m_BrFilterString);
|
const char *pStr = str_utf8_find_nocase(pItem->m_aName, g_Config.m_BrFilterString);
|
||||||
if(pStr)
|
if(pStr)
|
||||||
{
|
{
|
||||||
UI()->DoLabelStreamed(*pItem->m_pUIElement->Get(gs_OffsetColName + 0), &Button, pItem->m_aName, FontSize, TEXTALIGN_LEFT, Button.w, 1, true, (int)(pStr - pItem->m_aName));
|
UI()->DoLabelStreamed(*pItem->m_pUIElement->Rect(gs_OffsetColName + 0), &Button, pItem->m_aName, FontSize, TEXTALIGN_LEFT, Button.w, 1, true, (int)(pStr - pItem->m_aName));
|
||||||
TextRender()->TextColor(0.4f, 0.4f, 1.0f, 1);
|
TextRender()->TextColor(0.4f, 0.4f, 1.0f, 1);
|
||||||
UI()->DoLabelStreamed(*pItem->m_pUIElement->Get(gs_OffsetColName + 1), &Button, pStr, FontSize, TEXTALIGN_LEFT, Button.w, 1, true, (int)str_length(g_Config.m_BrFilterString), &pItem->m_pUIElement->Get(gs_OffsetColName + 0)->m_Cursor);
|
UI()->DoLabelStreamed(*pItem->m_pUIElement->Rect(gs_OffsetColName + 1), &Button, pStr, FontSize, TEXTALIGN_LEFT, Button.w, 1, true, (int)str_length(g_Config.m_BrFilterString), &pItem->m_pUIElement->Rect(gs_OffsetColName + 0)->m_Cursor);
|
||||||
TextRender()->TextColor(1, 1, 1, 1);
|
TextRender()->TextColor(1, 1, 1, 1);
|
||||||
UI()->DoLabelStreamed(*pItem->m_pUIElement->Get(gs_OffsetColName + 2), &Button, pStr + str_length(g_Config.m_BrFilterString), FontSize, TEXTALIGN_LEFT, Button.w, 1, true, -1, &pItem->m_pUIElement->Get(gs_OffsetColName + 1)->m_Cursor);
|
UI()->DoLabelStreamed(*pItem->m_pUIElement->Rect(gs_OffsetColName + 2), &Button, pStr + str_length(g_Config.m_BrFilterString), FontSize, TEXTALIGN_LEFT, Button.w, 1, true, -1, &pItem->m_pUIElement->Rect(gs_OffsetColName + 1)->m_Cursor);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
UI()->DoLabelStreamed(*pItem->m_pUIElement->Get(gs_OffsetColName), &Button, pItem->m_aName, FontSize, TEXTALIGN_LEFT, Button.w, 1, true);
|
UI()->DoLabelStreamed(*pItem->m_pUIElement->Rect(gs_OffsetColName), &Button, pItem->m_aName, FontSize, TEXTALIGN_LEFT, Button.w, 1, true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
UI()->DoLabelStreamed(*pItem->m_pUIElement->Get(gs_OffsetColName), &Button, pItem->m_aName, FontSize, TEXTALIGN_LEFT, Button.w, 1, true);
|
UI()->DoLabelStreamed(*pItem->m_pUIElement->Rect(gs_OffsetColName), &Button, pItem->m_aName, FontSize, TEXTALIGN_LEFT, Button.w, 1, true);
|
||||||
}
|
}
|
||||||
else if(ID == COL_MAP)
|
else if(ID == COL_MAP)
|
||||||
{
|
{
|
||||||
|
@ -379,7 +379,7 @@ void CMenus::RenderServerbrowserServerList(CUIRect View)
|
||||||
|
|
||||||
if(g_Config.m_BrIndicateFinished && pItem->m_HasRank == 1)
|
if(g_Config.m_BrIndicateFinished && pItem->m_HasRank == 1)
|
||||||
{
|
{
|
||||||
RenderBrowserIcons(*pItem->m_pUIElement->Get(gs_OffsetColFlagLock + 1), &Icon, TextRender()->DefaultTextColor(), TextRender()->DefaultTextOutlineColor(), "\xEF\x84\x9E", TEXTALIGN_CENTER);
|
RenderBrowserIcons(*pItem->m_pUIElement->Rect(gs_OffsetColFlagLock + 1), &Icon, TextRender()->DefaultTextColor(), TextRender()->DefaultTextOutlineColor(), "\xEF\x84\x9E", TEXTALIGN_CENTER);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -391,17 +391,17 @@ void CMenus::RenderServerbrowserServerList(CUIRect View)
|
||||||
const char *pStr = str_utf8_find_nocase(pItem->m_aMap, g_Config.m_BrFilterString);
|
const char *pStr = str_utf8_find_nocase(pItem->m_aMap, g_Config.m_BrFilterString);
|
||||||
if(pStr)
|
if(pStr)
|
||||||
{
|
{
|
||||||
UI()->DoLabelStreamed(*pItem->m_pUIElement->Get(gs_OffsetColMap + 0), &Button, pItem->m_aMap, FontSize, TEXTALIGN_LEFT, Button.w, 1, true, (int)(pStr - pItem->m_aMap));
|
UI()->DoLabelStreamed(*pItem->m_pUIElement->Rect(gs_OffsetColMap + 0), &Button, pItem->m_aMap, FontSize, TEXTALIGN_LEFT, Button.w, 1, true, (int)(pStr - pItem->m_aMap));
|
||||||
TextRender()->TextColor(0.4f, 0.4f, 1.0f, 1);
|
TextRender()->TextColor(0.4f, 0.4f, 1.0f, 1);
|
||||||
UI()->DoLabelStreamed(*pItem->m_pUIElement->Get(gs_OffsetColMap + 1), &Button, pStr, FontSize, TEXTALIGN_LEFT, Button.w, 1, true, (int)str_length(g_Config.m_BrFilterString), &pItem->m_pUIElement->Get(gs_OffsetColMap + 0)->m_Cursor);
|
UI()->DoLabelStreamed(*pItem->m_pUIElement->Rect(gs_OffsetColMap + 1), &Button, pStr, FontSize, TEXTALIGN_LEFT, Button.w, 1, true, (int)str_length(g_Config.m_BrFilterString), &pItem->m_pUIElement->Rect(gs_OffsetColMap + 0)->m_Cursor);
|
||||||
TextRender()->TextColor(1, 1, 1, 1);
|
TextRender()->TextColor(1, 1, 1, 1);
|
||||||
UI()->DoLabelStreamed(*pItem->m_pUIElement->Get(gs_OffsetColMap + 2), &Button, pStr + str_length(g_Config.m_BrFilterString), FontSize, TEXTALIGN_LEFT, Button.w, 1, true, -1, &pItem->m_pUIElement->Get(gs_OffsetColMap + 1)->m_Cursor);
|
UI()->DoLabelStreamed(*pItem->m_pUIElement->Rect(gs_OffsetColMap + 2), &Button, pStr + str_length(g_Config.m_BrFilterString), FontSize, TEXTALIGN_LEFT, Button.w, 1, true, -1, &pItem->m_pUIElement->Rect(gs_OffsetColMap + 1)->m_Cursor);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
UI()->DoLabelStreamed(*pItem->m_pUIElement->Get(gs_OffsetColMap), &Button, pItem->m_aMap, FontSize, TEXTALIGN_LEFT, Button.w, 1, true);
|
UI()->DoLabelStreamed(*pItem->m_pUIElement->Rect(gs_OffsetColMap), &Button, pItem->m_aMap, FontSize, TEXTALIGN_LEFT, Button.w, 1, true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
UI()->DoLabelStreamed(*pItem->m_pUIElement->Get(gs_OffsetColMap), &Button, pItem->m_aMap, FontSize, TEXTALIGN_LEFT, Button.w, 1, true);
|
UI()->DoLabelStreamed(*pItem->m_pUIElement->Rect(gs_OffsetColMap), &Button, pItem->m_aMap, FontSize, TEXTALIGN_LEFT, Button.w, 1, true);
|
||||||
}
|
}
|
||||||
else if(ID == COL_PLAYERS)
|
else if(ID == COL_PLAYERS)
|
||||||
{
|
{
|
||||||
|
@ -411,14 +411,14 @@ void CMenus::RenderServerbrowserServerList(CUIRect View)
|
||||||
{
|
{
|
||||||
Button.VSplitLeft(Button.h, &Icon, &Button);
|
Button.VSplitLeft(Button.h, &Icon, &Button);
|
||||||
Icon.Margin(2.0f, &Icon);
|
Icon.Margin(2.0f, &Icon);
|
||||||
RenderBrowserIcons(*pItem->m_pUIElement->Get(gs_OffsetColFav + 1), &Icon, {0.94f, 0.4f, 0.4f, 1}, TextRender()->DefaultTextOutlineColor(), "\xEF\x80\x84", TEXTALIGN_LEFT);
|
RenderBrowserIcons(*pItem->m_pUIElement->Rect(gs_OffsetColFav + 1), &Icon, {0.94f, 0.4f, 0.4f, 1}, TextRender()->DefaultTextOutlineColor(), "\xEF\x80\x84", TEXTALIGN_LEFT);
|
||||||
}
|
}
|
||||||
|
|
||||||
str_format(aTemp, sizeof(aTemp), "%i/%i", pItem->m_NumFilteredPlayers, ServerBrowser()->Max(*pItem));
|
str_format(aTemp, sizeof(aTemp), "%i/%i", pItem->m_NumFilteredPlayers, ServerBrowser()->Max(*pItem));
|
||||||
if(g_Config.m_BrFilterString[0] && (pItem->m_QuickSearchHit & IServerBrowser::QUICK_PLAYER))
|
if(g_Config.m_BrFilterString[0] && (pItem->m_QuickSearchHit & IServerBrowser::QUICK_PLAYER))
|
||||||
TextRender()->TextColor(0.4f, 0.4f, 1.0f, 1);
|
TextRender()->TextColor(0.4f, 0.4f, 1.0f, 1);
|
||||||
float FontSize = 12.0f;
|
float FontSize = 12.0f;
|
||||||
UI()->DoLabelStreamed(*pItem->m_pUIElement->Get(gs_OffsetColPlayers), &Button, aTemp, FontSize, TEXTALIGN_RIGHT, -1, 1, false);
|
UI()->DoLabelStreamed(*pItem->m_pUIElement->Rect(gs_OffsetColPlayers), &Button, aTemp, FontSize, TEXTALIGN_RIGHT, -1, 1, false);
|
||||||
TextRender()->TextColor(1, 1, 1, 1);
|
TextRender()->TextColor(1, 1, 1, 1);
|
||||||
}
|
}
|
||||||
else if(ID == COL_PING)
|
else if(ID == COL_PING)
|
||||||
|
@ -432,14 +432,14 @@ void CMenus::RenderServerbrowserServerList(CUIRect View)
|
||||||
}
|
}
|
||||||
|
|
||||||
float FontSize = 12.0f;
|
float FontSize = 12.0f;
|
||||||
UI()->DoLabelStreamed(*pItem->m_pUIElement->Get(gs_OffsetColPing), &Button, aTemp, FontSize, TEXTALIGN_RIGHT, -1, 1, false);
|
UI()->DoLabelStreamed(*pItem->m_pUIElement->Rect(gs_OffsetColPing), &Button, aTemp, FontSize, TEXTALIGN_RIGHT, -1, 1, false);
|
||||||
TextRender()->TextColor(1.0f, 1.0f, 1.0f, 1.0f);
|
TextRender()->TextColor(1.0f, 1.0f, 1.0f, 1.0f);
|
||||||
}
|
}
|
||||||
else if(ID == COL_VERSION)
|
else if(ID == COL_VERSION)
|
||||||
{
|
{
|
||||||
const char *pVersion = pItem->m_aVersion;
|
const char *pVersion = pItem->m_aVersion;
|
||||||
float FontSize = 12.0f;
|
float FontSize = 12.0f;
|
||||||
UI()->DoLabelStreamed(*pItem->m_pUIElement->Get(gs_OffsetColVersion), &Button, pVersion, FontSize, TEXTALIGN_RIGHT, -1, 1, false);
|
UI()->DoLabelStreamed(*pItem->m_pUIElement->Rect(gs_OffsetColVersion), &Button, pVersion, FontSize, TEXTALIGN_RIGHT, -1, 1, false);
|
||||||
}
|
}
|
||||||
else if(ID == COL_GAMETYPE)
|
else if(ID == COL_GAMETYPE)
|
||||||
{
|
{
|
||||||
|
@ -466,11 +466,11 @@ void CMenus::RenderServerbrowserServerList(CUIRect View)
|
||||||
|
|
||||||
ColorRGBA rgb = color_cast<ColorRGBA>(hsl);
|
ColorRGBA rgb = color_cast<ColorRGBA>(hsl);
|
||||||
TextRender()->TextColor(rgb);
|
TextRender()->TextColor(rgb);
|
||||||
UI()->DoLabelStreamed(*pItem->m_pUIElement->Get(gs_OffsetColGameType), &Button, pItem->m_aGameType, FontSize, TEXTALIGN_LEFT, Button.w, 1, true);
|
UI()->DoLabelStreamed(*pItem->m_pUIElement->Rect(gs_OffsetColGameType), &Button, pItem->m_aGameType, FontSize, TEXTALIGN_LEFT, Button.w, 1, true);
|
||||||
TextRender()->TextColor(1.0f, 1.0f, 1.0f, 1.0f);
|
TextRender()->TextColor(1.0f, 1.0f, 1.0f, 1.0f);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
UI()->DoLabelStreamed(*pItem->m_pUIElement->Get(gs_OffsetColGameType), &Button, pItem->m_aGameType, FontSize, TEXTALIGN_LEFT, Button.w, 1, true);
|
UI()->DoLabelStreamed(*pItem->m_pUIElement->Rect(gs_OffsetColGameType), &Button, pItem->m_aGameType, FontSize, TEXTALIGN_LEFT, Button.w, 1, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include <game/client/gameclient.h>
|
#include <game/client/gameclient.h>
|
||||||
#include <game/client/render.h>
|
#include <game/client/render.h>
|
||||||
#include <game/client/ui.h>
|
#include <game/client/ui.h>
|
||||||
|
#include <game/client/ui_scrollregion.h>
|
||||||
#include <game/localization.h>
|
#include <game/localization.h>
|
||||||
|
|
||||||
#include "menus.h"
|
#include "menus.h"
|
||||||
|
@ -450,14 +451,30 @@ void CMenus::RenderServerInfo(CUIRect MainView)
|
||||||
}
|
}
|
||||||
|
|
||||||
// motd
|
// motd
|
||||||
Motd.HSplitTop(10.0f, 0, &Motd);
|
const float MotdFontSize = 16.0f;
|
||||||
|
Motd.HSplitTop(10.0f, nullptr, &Motd);
|
||||||
Motd.Draw(ColorRGBA(1, 1, 1, 0.25f), IGraphics::CORNER_ALL, 10.0f);
|
Motd.Draw(ColorRGBA(1, 1, 1, 0.25f), IGraphics::CORNER_ALL, 10.0f);
|
||||||
Motd.Margin(5.0f, &Motd);
|
Motd.HMargin(5.0f, &Motd);
|
||||||
y = 0.0f;
|
Motd.VMargin(10.0f, &Motd);
|
||||||
x = 5.0f;
|
|
||||||
TextRender()->Text(0, Motd.x + x, Motd.y + y, 32, Localize("MOTD"), -1.0f);
|
CUIRect MotdHeader;
|
||||||
y += 32.0f + 5.0f;
|
Motd.HSplitTop(2.0f * MotdFontSize, &MotdHeader, &Motd);
|
||||||
TextRender()->Text(0, Motd.x + x, Motd.y + y, 16, m_pClient->m_Motd.m_aServerMotd, Motd.w);
|
Motd.HSplitTop(5.0f, nullptr, &Motd);
|
||||||
|
TextRender()->Text(nullptr, MotdHeader.x, MotdHeader.y, 2.0f * MotdFontSize, Localize("MOTD"), -1.0f);
|
||||||
|
|
||||||
|
static CScrollRegion s_ScrollRegion;
|
||||||
|
vec2 ScrollOffset(0.0f, 0.0f);
|
||||||
|
CScrollRegionParams ScrollParams;
|
||||||
|
ScrollParams.m_ScrollUnit = 5 * MotdFontSize;
|
||||||
|
s_ScrollRegion.Begin(&Motd, &ScrollOffset, &ScrollParams);
|
||||||
|
Motd.y += ScrollOffset.y;
|
||||||
|
|
||||||
|
CUIRect MotdTextArea;
|
||||||
|
Motd.HSplitTop((str_countchr(m_pClient->m_Motd.m_aServerMotd, '\n') + 1) * MotdFontSize, &MotdTextArea, &Motd);
|
||||||
|
s_ScrollRegion.AddRect(MotdTextArea);
|
||||||
|
TextRender()->Text(nullptr, MotdTextArea.x, MotdTextArea.y, MotdFontSize, m_pClient->m_Motd.m_aServerMotd, MotdTextArea.w);
|
||||||
|
|
||||||
|
s_ScrollRegion.End();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CMenus::RenderServerControlServer(CUIRect MainView)
|
bool CMenus::RenderServerControlServer(CUIRect MainView)
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include <game/client/gameclient.h>
|
#include <game/client/gameclient.h>
|
||||||
#include <game/client/render.h>
|
#include <game/client/render.h>
|
||||||
#include <game/client/ui.h>
|
#include <game/client/ui.h>
|
||||||
|
#include <game/client/ui_scrollregion.h>
|
||||||
#include <game/localization.h>
|
#include <game/localization.h>
|
||||||
|
|
||||||
#include "binds.h"
|
#include "binds.h"
|
||||||
|
@ -927,7 +928,7 @@ float CMenus::RenderSettingsControlsJoystick(CUIRect View)
|
||||||
const float Spacing = 2.0f;
|
const float Spacing = 2.0f;
|
||||||
const float BackgroundHeight = NumOptions * (ButtonHeight + Spacing) + (NumOptions == 1 ? 0 : Spacing);
|
const float BackgroundHeight = NumOptions * (ButtonHeight + Spacing) + (NumOptions == 1 ? 0 : Spacing);
|
||||||
if(View.h < BackgroundHeight)
|
if(View.h < BackgroundHeight)
|
||||||
return BackgroundHeight; // TODO: make this less hacky by porting CScrollRegion from vanilla
|
return BackgroundHeight;
|
||||||
|
|
||||||
View.HSplitTop(BackgroundHeight, &View, 0);
|
View.HSplitTop(BackgroundHeight, &View, 0);
|
||||||
|
|
||||||
|
@ -1107,30 +1108,28 @@ void CMenus::RenderSettingsControls(CUIRect MainView)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// controls in a scrollable listbox
|
// scrollable controls
|
||||||
static int s_ControlsList = 0;
|
|
||||||
static int s_SelectedControl = -1;
|
|
||||||
static float s_ScrollValue = 0;
|
|
||||||
static int s_OldSelected = 0;
|
|
||||||
static float s_JoystickSettingsHeight = 0.0f; // we calculate this later and don't render until enough space is available
|
static float s_JoystickSettingsHeight = 0.0f; // we calculate this later and don't render until enough space is available
|
||||||
// Hacky values: Size of 10.0f per item for smoother scrolling, 72 elements
|
static CScrollRegion s_ScrollRegion;
|
||||||
// fits the current size of controls settings
|
vec2 ScrollOffset(0.0f, 0.0f);
|
||||||
const float PseudoItemSize = 10.0f;
|
CScrollRegionParams ScrollParams;
|
||||||
UiDoListboxStart(&s_ControlsList, &MainView, PseudoItemSize, Localize("Controls"), "", 72 + (int)ceilf(s_JoystickSettingsHeight / PseudoItemSize + 0.5f), 1, s_SelectedControl, s_ScrollValue);
|
ScrollParams.m_ScrollUnit = 120.0f;
|
||||||
|
s_ScrollRegion.Begin(&MainView, &ScrollOffset, &ScrollParams);
|
||||||
CUIRect MouseSettings, MovementSettings, WeaponSettings, VotingSettings, ChatSettings, DummySettings, MiscSettings, JoystickSettings, ResetButton;
|
MainView.y += ScrollOffset.y;
|
||||||
CListboxItem Item = UiDoListboxNextItem(&s_OldSelected, false, false, true);
|
|
||||||
Item.m_Rect.HSplitTop(10.0f, 0, &Item.m_Rect);
|
|
||||||
Item.m_Rect.VSplitMid(&MouseSettings, &VotingSettings);
|
|
||||||
|
|
||||||
const float FontSize = 14.0f;
|
const float FontSize = 14.0f;
|
||||||
const float Margin = 10.0f;
|
const float Margin = 10.0f;
|
||||||
const float HeaderHeight = FontSize + 5.0f + Margin;
|
const float HeaderHeight = FontSize + 5.0f + Margin;
|
||||||
|
|
||||||
|
CUIRect MouseSettings, MovementSettings, WeaponSettings, VotingSettings, ChatSettings, DummySettings, MiscSettings, JoystickSettings, ResetButton;
|
||||||
|
MainView.VSplitMid(&MouseSettings, &VotingSettings);
|
||||||
|
|
||||||
// mouse settings
|
// mouse settings
|
||||||
{
|
{
|
||||||
MouseSettings.VMargin(5.0f, &MouseSettings);
|
MouseSettings.VMargin(5.0f, &MouseSettings);
|
||||||
MouseSettings.HSplitTop(80.0f, &MouseSettings, &JoystickSettings);
|
MouseSettings.HSplitTop(80.0f, &MouseSettings, &JoystickSettings);
|
||||||
|
if(s_ScrollRegion.AddRect(MouseSettings))
|
||||||
|
{
|
||||||
MouseSettings.Draw(ColorRGBA(1, 1, 1, 0.25f), IGraphics::CORNER_ALL, 10.0f);
|
MouseSettings.Draw(ColorRGBA(1, 1, 1, 0.25f), IGraphics::CORNER_ALL, 10.0f);
|
||||||
MouseSettings.VMargin(10.0f, &MouseSettings);
|
MouseSettings.VMargin(10.0f, &MouseSettings);
|
||||||
|
|
||||||
|
@ -1147,24 +1146,30 @@ void CMenus::RenderSettingsControls(CUIRect MainView)
|
||||||
MouseSettings.HSplitTop(20.0f, &Button, &MouseSettings);
|
MouseSettings.HSplitTop(20.0f, &Button, &MouseSettings);
|
||||||
UI()->DoScrollbarOption(&g_Config.m_UiMousesens, &g_Config.m_UiMousesens, &Button, Localize("UI mouse sens."), 1, 500, &CUI::ms_LogarithmicScrollbarScale, CUI::SCROLLBAR_OPTION_NOCLAMPVALUE);
|
UI()->DoScrollbarOption(&g_Config.m_UiMousesens, &g_Config.m_UiMousesens, &Button, Localize("UI mouse sens."), 1, 500, &CUI::ms_LogarithmicScrollbarScale, CUI::SCROLLBAR_OPTION_NOCLAMPVALUE);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// joystick settings
|
// joystick settings
|
||||||
{
|
{
|
||||||
JoystickSettings.HSplitTop(Margin, 0, &JoystickSettings);
|
JoystickSettings.HSplitTop(Margin, 0, &JoystickSettings);
|
||||||
JoystickSettings.HSplitTop(s_JoystickSettingsHeight, &JoystickSettings, &MovementSettings);
|
JoystickSettings.HSplitTop(s_JoystickSettingsHeight + HeaderHeight + Margin, &JoystickSettings, &MovementSettings);
|
||||||
|
if(s_ScrollRegion.AddRect(JoystickSettings))
|
||||||
|
{
|
||||||
JoystickSettings.Draw(ColorRGBA(1, 1, 1, 0.25f), IGraphics::CORNER_ALL, 10.0f);
|
JoystickSettings.Draw(ColorRGBA(1, 1, 1, 0.25f), IGraphics::CORNER_ALL, 10.0f);
|
||||||
JoystickSettings.VMargin(Margin, &JoystickSettings);
|
JoystickSettings.VMargin(Margin, &JoystickSettings);
|
||||||
|
|
||||||
TextRender()->Text(0, JoystickSettings.x, JoystickSettings.y + (HeaderHeight - FontSize) / 2.f, FontSize, Localize("Controller"), -1.0f);
|
TextRender()->Text(0, JoystickSettings.x, JoystickSettings.y + (HeaderHeight - FontSize) / 2.f, FontSize, Localize("Controller"), -1.0f);
|
||||||
|
|
||||||
JoystickSettings.HSplitTop(HeaderHeight, 0, &JoystickSettings);
|
JoystickSettings.HSplitTop(HeaderHeight, 0, &JoystickSettings);
|
||||||
s_JoystickSettingsHeight = RenderSettingsControlsJoystick(JoystickSettings) + HeaderHeight + Margin; // + Margin for another bottom margin
|
s_JoystickSettingsHeight = RenderSettingsControlsJoystick(JoystickSettings);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// movement settings
|
// movement settings
|
||||||
{
|
{
|
||||||
MovementSettings.HSplitTop(Margin, 0, &MovementSettings);
|
MovementSettings.HSplitTop(Margin, 0, &MovementSettings);
|
||||||
MovementSettings.HSplitTop(365.0f, &MovementSettings, &WeaponSettings);
|
MovementSettings.HSplitTop(365.0f, &MovementSettings, &WeaponSettings);
|
||||||
|
if(s_ScrollRegion.AddRect(MovementSettings))
|
||||||
|
{
|
||||||
MovementSettings.Draw(ColorRGBA(1, 1, 1, 0.25f), IGraphics::CORNER_ALL, 10.0f);
|
MovementSettings.Draw(ColorRGBA(1, 1, 1, 0.25f), IGraphics::CORNER_ALL, 10.0f);
|
||||||
MovementSettings.VMargin(Margin, &MovementSettings);
|
MovementSettings.VMargin(Margin, &MovementSettings);
|
||||||
|
|
||||||
|
@ -1173,11 +1178,14 @@ void CMenus::RenderSettingsControls(CUIRect MainView)
|
||||||
MovementSettings.HSplitTop(HeaderHeight, 0, &MovementSettings);
|
MovementSettings.HSplitTop(HeaderHeight, 0, &MovementSettings);
|
||||||
DoSettingsControlsButtons(0, 15, MovementSettings);
|
DoSettingsControlsButtons(0, 15, MovementSettings);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// weapon settings
|
// weapon settings
|
||||||
{
|
{
|
||||||
WeaponSettings.HSplitTop(Margin, 0, &WeaponSettings);
|
WeaponSettings.HSplitTop(Margin, 0, &WeaponSettings);
|
||||||
WeaponSettings.HSplitTop(190.0f, &WeaponSettings, &ResetButton);
|
WeaponSettings.HSplitTop(190.0f, &WeaponSettings, &ResetButton);
|
||||||
|
if(s_ScrollRegion.AddRect(WeaponSettings))
|
||||||
|
{
|
||||||
WeaponSettings.Draw(ColorRGBA(1, 1, 1, 0.25f), IGraphics::CORNER_ALL, 10.0f);
|
WeaponSettings.Draw(ColorRGBA(1, 1, 1, 0.25f), IGraphics::CORNER_ALL, 10.0f);
|
||||||
WeaponSettings.VMargin(Margin, &WeaponSettings);
|
WeaponSettings.VMargin(Margin, &WeaponSettings);
|
||||||
|
|
||||||
|
@ -1186,15 +1194,17 @@ void CMenus::RenderSettingsControls(CUIRect MainView)
|
||||||
WeaponSettings.HSplitTop(HeaderHeight, 0, &WeaponSettings);
|
WeaponSettings.HSplitTop(HeaderHeight, 0, &WeaponSettings);
|
||||||
DoSettingsControlsButtons(15, 22, WeaponSettings);
|
DoSettingsControlsButtons(15, 22, WeaponSettings);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// defaults
|
// defaults
|
||||||
{
|
{
|
||||||
ResetButton.HSplitTop(Margin, 0, &ResetButton);
|
ResetButton.HSplitTop(Margin, 0, &ResetButton);
|
||||||
ResetButton.HSplitTop(40.0f, &ResetButton, 0);
|
ResetButton.HSplitTop(40.0f, &ResetButton, 0);
|
||||||
|
if(s_ScrollRegion.AddRect(ResetButton))
|
||||||
|
{
|
||||||
ResetButton.Draw(ColorRGBA(1, 1, 1, 0.25f), IGraphics::CORNER_ALL, 10.0f);
|
ResetButton.Draw(ColorRGBA(1, 1, 1, 0.25f), IGraphics::CORNER_ALL, 10.0f);
|
||||||
ResetButton.HMargin(10.0f, &ResetButton);
|
ResetButton.HMargin(10.0f, &ResetButton);
|
||||||
ResetButton.VMargin(30.0f, &ResetButton);
|
ResetButton.VMargin(30.0f, &ResetButton);
|
||||||
ResetButton.HSplitTop(20.0f, &ResetButton, 0);
|
|
||||||
static CButtonContainer s_DefaultButton;
|
static CButtonContainer s_DefaultButton;
|
||||||
if(DoButton_Menu(&s_DefaultButton, Localize("Reset to defaults"), 0, &ResetButton))
|
if(DoButton_Menu(&s_DefaultButton, Localize("Reset to defaults"), 0, &ResetButton))
|
||||||
{
|
{
|
||||||
|
@ -1213,11 +1223,14 @@ void CMenus::RenderSettingsControls(CUIRect MainView)
|
||||||
g_Config.m_UiControllerSens = 100;
|
g_Config.m_UiControllerSens = 100;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// voting settings
|
// voting settings
|
||||||
{
|
{
|
||||||
VotingSettings.VMargin(5.0f, &VotingSettings);
|
VotingSettings.VMargin(5.0f, &VotingSettings);
|
||||||
VotingSettings.HSplitTop(80.0f, &VotingSettings, &ChatSettings);
|
VotingSettings.HSplitTop(80.0f, &VotingSettings, &ChatSettings);
|
||||||
|
if(s_ScrollRegion.AddRect(VotingSettings))
|
||||||
|
{
|
||||||
VotingSettings.Draw(ColorRGBA(1, 1, 1, 0.25f), IGraphics::CORNER_ALL, 10.0f);
|
VotingSettings.Draw(ColorRGBA(1, 1, 1, 0.25f), IGraphics::CORNER_ALL, 10.0f);
|
||||||
VotingSettings.VMargin(Margin, &VotingSettings);
|
VotingSettings.VMargin(Margin, &VotingSettings);
|
||||||
|
|
||||||
|
@ -1226,11 +1239,14 @@ void CMenus::RenderSettingsControls(CUIRect MainView)
|
||||||
VotingSettings.HSplitTop(HeaderHeight, 0, &VotingSettings);
|
VotingSettings.HSplitTop(HeaderHeight, 0, &VotingSettings);
|
||||||
DoSettingsControlsButtons(22, 24, VotingSettings);
|
DoSettingsControlsButtons(22, 24, VotingSettings);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// chat settings
|
// chat settings
|
||||||
{
|
{
|
||||||
ChatSettings.HSplitTop(Margin, 0, &ChatSettings);
|
ChatSettings.HSplitTop(Margin, 0, &ChatSettings);
|
||||||
ChatSettings.HSplitTop(145.0f, &ChatSettings, &DummySettings);
|
ChatSettings.HSplitTop(145.0f, &ChatSettings, &DummySettings);
|
||||||
|
if(s_ScrollRegion.AddRect(ChatSettings))
|
||||||
|
{
|
||||||
ChatSettings.Draw(ColorRGBA(1, 1, 1, 0.25f), IGraphics::CORNER_ALL, 10.0f);
|
ChatSettings.Draw(ColorRGBA(1, 1, 1, 0.25f), IGraphics::CORNER_ALL, 10.0f);
|
||||||
ChatSettings.VMargin(Margin, &ChatSettings);
|
ChatSettings.VMargin(Margin, &ChatSettings);
|
||||||
|
|
||||||
|
@ -1239,11 +1255,14 @@ void CMenus::RenderSettingsControls(CUIRect MainView)
|
||||||
ChatSettings.HSplitTop(HeaderHeight, 0, &ChatSettings);
|
ChatSettings.HSplitTop(HeaderHeight, 0, &ChatSettings);
|
||||||
DoSettingsControlsButtons(24, 29, ChatSettings);
|
DoSettingsControlsButtons(24, 29, ChatSettings);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// dummy settings
|
// dummy settings
|
||||||
{
|
{
|
||||||
DummySettings.HSplitTop(Margin, 0, &DummySettings);
|
DummySettings.HSplitTop(Margin, 0, &DummySettings);
|
||||||
DummySettings.HSplitTop(100.0f, &DummySettings, &MiscSettings);
|
DummySettings.HSplitTop(100.0f, &DummySettings, &MiscSettings);
|
||||||
|
if(s_ScrollRegion.AddRect(DummySettings))
|
||||||
|
{
|
||||||
DummySettings.Draw(ColorRGBA(1, 1, 1, 0.25f), IGraphics::CORNER_ALL, 10.0f);
|
DummySettings.Draw(ColorRGBA(1, 1, 1, 0.25f), IGraphics::CORNER_ALL, 10.0f);
|
||||||
DummySettings.VMargin(Margin, &DummySettings);
|
DummySettings.VMargin(Margin, &DummySettings);
|
||||||
|
|
||||||
|
@ -1252,11 +1271,14 @@ void CMenus::RenderSettingsControls(CUIRect MainView)
|
||||||
DummySettings.HSplitTop(HeaderHeight, 0, &DummySettings);
|
DummySettings.HSplitTop(HeaderHeight, 0, &DummySettings);
|
||||||
DoSettingsControlsButtons(29, 32, DummySettings);
|
DoSettingsControlsButtons(29, 32, DummySettings);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// misc settings
|
// misc settings
|
||||||
{
|
{
|
||||||
MiscSettings.HSplitTop(Margin, 0, &MiscSettings);
|
MiscSettings.HSplitTop(Margin, 0, &MiscSettings);
|
||||||
MiscSettings.HSplitTop(300.0f, &MiscSettings, 0);
|
MiscSettings.HSplitTop(300.0f, &MiscSettings, 0);
|
||||||
|
if(s_ScrollRegion.AddRect(MiscSettings))
|
||||||
|
{
|
||||||
MiscSettings.Draw(ColorRGBA(1, 1, 1, 0.25f), IGraphics::CORNER_ALL, 10.0f);
|
MiscSettings.Draw(ColorRGBA(1, 1, 1, 0.25f), IGraphics::CORNER_ALL, 10.0f);
|
||||||
MiscSettings.VMargin(Margin, &MiscSettings);
|
MiscSettings.VMargin(Margin, &MiscSettings);
|
||||||
|
|
||||||
|
@ -1265,8 +1287,9 @@ void CMenus::RenderSettingsControls(CUIRect MainView)
|
||||||
MiscSettings.HSplitTop(HeaderHeight, 0, &MiscSettings);
|
MiscSettings.HSplitTop(HeaderHeight, 0, &MiscSettings);
|
||||||
DoSettingsControlsButtons(32, 44, MiscSettings);
|
DoSettingsControlsButtons(32, 44, MiscSettings);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
UiDoListboxEnd(&s_ScrollValue, 0);
|
s_ScrollRegion.End();
|
||||||
}
|
}
|
||||||
|
|
||||||
int CMenus::RenderDropDown(int &CurDropDownState, CUIRect *pRect, int CurSelection, const void **pIDs, const char **pStr, int PickNum, CButtonContainer *pButtonContainer, float &ScrollVal)
|
int CMenus::RenderDropDown(int &CurDropDownState, CUIRect *pRect, int CurSelection, const void **pIDs, const char **pStr, int PickNum, CButtonContainer *pButtonContainer, float &ScrollVal)
|
||||||
|
|
|
@ -101,7 +101,7 @@ void CNamePlates::RenderNameplatePos(vec2 Position, const CNetObj_PlayerInfo *pP
|
||||||
// create nameplates at standard zoom
|
// create nameplates at standard zoom
|
||||||
float ScreenX0, ScreenY0, ScreenX1, ScreenY1;
|
float ScreenX0, ScreenY0, ScreenX1, ScreenY1;
|
||||||
Graphics()->GetScreen(&ScreenX0, &ScreenY0, &ScreenX1, &ScreenY1);
|
Graphics()->GetScreen(&ScreenX0, &ScreenY0, &ScreenX1, &ScreenY1);
|
||||||
RenderTools()->MapScreenToGroup(m_pClient->m_Camera.m_Center.x, m_pClient->m_Camera.m_Center.y, Layers()->GameGroup());
|
RenderTools()->MapScreenToInterface(m_pClient->m_Camera.m_Center.x, m_pClient->m_Camera.m_Center.y);
|
||||||
|
|
||||||
m_aNamePlates[ClientID].m_NameTextWidth = TextRender()->TextWidth(0, FontSize, pName, -1, -1.0f);
|
m_aNamePlates[ClientID].m_NameTextWidth = TextRender()->TextWidth(0, FontSize, pName, -1, -1.0f);
|
||||||
|
|
||||||
|
@ -126,7 +126,7 @@ void CNamePlates::RenderNameplatePos(vec2 Position, const CNetObj_PlayerInfo *pP
|
||||||
// create nameplates at standard zoom
|
// create nameplates at standard zoom
|
||||||
float ScreenX0, ScreenY0, ScreenX1, ScreenY1;
|
float ScreenX0, ScreenY0, ScreenX1, ScreenY1;
|
||||||
Graphics()->GetScreen(&ScreenX0, &ScreenY0, &ScreenX1, &ScreenY1);
|
Graphics()->GetScreen(&ScreenX0, &ScreenY0, &ScreenX1, &ScreenY1);
|
||||||
RenderTools()->MapScreenToGroup(m_pClient->m_Camera.m_Center.x, m_pClient->m_Camera.m_Center.y, Layers()->GameGroup());
|
RenderTools()->MapScreenToInterface(m_pClient->m_Camera.m_Center.x, m_pClient->m_Camera.m_Center.y);
|
||||||
|
|
||||||
m_aNamePlates[ClientID].m_ClanNameTextWidth = TextRender()->TextWidth(0, FontSizeClan, pClan, -1, -1.0f);
|
m_aNamePlates[ClientID].m_ClanNameTextWidth = TextRender()->TextWidth(0, FontSizeClan, pClan, -1, -1.0f);
|
||||||
|
|
||||||
|
|
|
@ -374,6 +374,8 @@ void CGameClient::OnInit()
|
||||||
|
|
||||||
void CGameClient::OnUpdate()
|
void CGameClient::OnUpdate()
|
||||||
{
|
{
|
||||||
|
CUIElementBase::Init(UI()); // update static pointer because game and editor use separate UI
|
||||||
|
|
||||||
// handle mouse movement
|
// handle mouse movement
|
||||||
float x = 0.0f, y = 0.0f;
|
float x = 0.0f, y = 0.0f;
|
||||||
IInput::ECursorType CursorType = Input()->CursorRelative(&x, &y);
|
IInput::ECursorType CursorType = Input()->CursorRelative(&x, &y);
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#include <game/generated/protocol.h>
|
#include <game/generated/protocol.h>
|
||||||
|
|
||||||
#include <game/mapitems.h>
|
#include <game/mapitems.h>
|
||||||
|
#include <game/mapitems_ex.h>
|
||||||
|
|
||||||
static float gs_SpriteWScale;
|
static float gs_SpriteWScale;
|
||||||
static float gs_SpriteHScale;
|
static float gs_SpriteHScale;
|
||||||
|
@ -389,10 +390,15 @@ void CRenderTools::CalcScreenParams(float Aspect, float Zoom, float *pWidth, flo
|
||||||
}
|
}
|
||||||
|
|
||||||
void CRenderTools::MapScreenToWorld(float CenterX, float CenterY, float ParallaxX, float ParallaxY,
|
void CRenderTools::MapScreenToWorld(float CenterX, float CenterY, float ParallaxX, float ParallaxY,
|
||||||
float OffsetX, float OffsetY, float Aspect, float Zoom, float *pPoints)
|
float ParallaxZoom, float OffsetX, float OffsetY, float Aspect, float Zoom, float *pPoints)
|
||||||
{
|
{
|
||||||
float Width, Height;
|
float Width, Height;
|
||||||
CalcScreenParams(Aspect, Zoom, &Width, &Height);
|
CalcScreenParams(Aspect, Zoom, &Width, &Height);
|
||||||
|
|
||||||
|
float Scale = (ParallaxZoom * (Zoom - 1.0f) + 100.0f) / 100.0f / Zoom;
|
||||||
|
Width *= Scale;
|
||||||
|
Height *= Scale;
|
||||||
|
|
||||||
CenterX *= ParallaxX / 100.0f;
|
CenterX *= ParallaxX / 100.0f;
|
||||||
CenterY *= ParallaxY / 100.0f;
|
CenterY *= ParallaxY / 100.0f;
|
||||||
pPoints[0] = OffsetX + CenterX - Width / 2;
|
pPoints[0] = OffsetX + CenterX - Width / 2;
|
||||||
|
@ -401,10 +407,19 @@ void CRenderTools::MapScreenToWorld(float CenterX, float CenterY, float Parallax
|
||||||
pPoints[3] = pPoints[1] + Height;
|
pPoints[3] = pPoints[1] + Height;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CRenderTools::MapScreenToGroup(float CenterX, float CenterY, CMapItemGroup *pGroup, float Zoom)
|
void CRenderTools::MapScreenToGroup(float CenterX, float CenterY, CMapItemGroup *pGroup, CMapItemGroupEx *pGroupEx, float Zoom)
|
||||||
{
|
{
|
||||||
|
float ParallaxZoom = GetParallaxZoom(pGroup, pGroupEx);
|
||||||
float aPoints[4];
|
float aPoints[4];
|
||||||
MapScreenToWorld(CenterX, CenterY, pGroup->m_ParallaxX, pGroup->m_ParallaxY,
|
MapScreenToWorld(CenterX, CenterY, pGroup->m_ParallaxX, pGroup->m_ParallaxY, ParallaxZoom,
|
||||||
pGroup->m_OffsetX, pGroup->m_OffsetY, Graphics()->ScreenAspect(), Zoom, aPoints);
|
pGroup->m_OffsetX, pGroup->m_OffsetY, Graphics()->ScreenAspect(), Zoom, aPoints);
|
||||||
Graphics()->MapScreen(aPoints[0], aPoints[1], aPoints[2], aPoints[3]);
|
Graphics()->MapScreen(aPoints[0], aPoints[1], aPoints[2], aPoints[3]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CRenderTools::MapScreenToInterface(float CenterX, float CenterY)
|
||||||
|
{
|
||||||
|
float aPoints[4];
|
||||||
|
MapScreenToWorld(CenterX, CenterY, 100.0f, 100.0f, 100.0f,
|
||||||
|
0, 0, Graphics()->ScreenAspect(), 1.0f, aPoints);
|
||||||
|
Graphics()->MapScreen(aPoints[0], aPoints[1], aPoints[2], aPoints[3]);
|
||||||
|
}
|
||||||
|
|
|
@ -20,6 +20,7 @@ struct CDataSprite;
|
||||||
struct CDataSprite;
|
struct CDataSprite;
|
||||||
struct CEnvPoint;
|
struct CEnvPoint;
|
||||||
struct CMapItemGroup;
|
struct CMapItemGroup;
|
||||||
|
struct CMapItemGroupEx;
|
||||||
struct CQuad;
|
struct CQuad;
|
||||||
|
|
||||||
class CTeeRenderInfo
|
class CTeeRenderInfo
|
||||||
|
@ -126,8 +127,9 @@ public:
|
||||||
// helpers
|
// helpers
|
||||||
void CalcScreenParams(float Aspect, float Zoom, float *pWidth, float *pHeight);
|
void CalcScreenParams(float Aspect, float Zoom, float *pWidth, float *pHeight);
|
||||||
void MapScreenToWorld(float CenterX, float CenterY, float ParallaxX, float ParallaxY,
|
void MapScreenToWorld(float CenterX, float CenterY, float ParallaxX, float ParallaxY,
|
||||||
float OffsetX, float OffsetY, float Aspect, float Zoom, float *pPoints);
|
float ParallaxZoom, float OffsetX, float OffsetY, float Aspect, float Zoom, float *pPoints);
|
||||||
void MapScreenToGroup(float CenterX, float CenterY, CMapItemGroup *pGroup, float Zoom = 1.0f);
|
void MapScreenToGroup(float CenterX, float CenterY, CMapItemGroup *pGroup, CMapItemGroupEx *pGroupEx, float Zoom);
|
||||||
|
void MapScreenToInterface(float CenterX, float CenterY);
|
||||||
|
|
||||||
// DDRace
|
// DDRace
|
||||||
|
|
||||||
|
|
|
@ -82,6 +82,13 @@ const CLinearScrollbarScale CUI::ms_LinearScrollbarScale;
|
||||||
const CLogarithmicScrollbarScale CUI::ms_LogarithmicScrollbarScale(25);
|
const CLogarithmicScrollbarScale CUI::ms_LogarithmicScrollbarScale(25);
|
||||||
float CUI::ms_FontmodHeight = 0.8f;
|
float CUI::ms_FontmodHeight = 0.8f;
|
||||||
|
|
||||||
|
CUI *CUIElementBase::s_pUI = nullptr;
|
||||||
|
|
||||||
|
IClient *CUIElementBase::Client() const { return s_pUI->Client(); }
|
||||||
|
IGraphics *CUIElementBase::Graphics() const { return s_pUI->Graphics(); }
|
||||||
|
IInput *CUIElementBase::Input() const { return s_pUI->Input(); }
|
||||||
|
ITextRender *CUIElementBase::TextRender() const { return s_pUI->TextRender(); }
|
||||||
|
|
||||||
void CUI::Init(IKernel *pKernel)
|
void CUI::Init(IKernel *pKernel)
|
||||||
{
|
{
|
||||||
m_pClient = pKernel->RequestInterface<IClient>();
|
m_pClient = pKernel->RequestInterface<IClient>();
|
||||||
|
@ -90,6 +97,7 @@ void CUI::Init(IKernel *pKernel)
|
||||||
m_pTextRender = pKernel->RequestInterface<ITextRender>();
|
m_pTextRender = pKernel->RequestInterface<ITextRender>();
|
||||||
InitInputs(m_pInput->GetEventsRaw(), m_pInput->GetEventCountRaw());
|
InitInputs(m_pInput->GetEventsRaw(), m_pInput->GetEventCountRaw());
|
||||||
CUIRect::Init(m_pGraphics);
|
CUIRect::Init(m_pGraphics);
|
||||||
|
CUIElementBase::Init(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CUI::InitInputs(IInput::CEvent *pInputEventsArray, int *pInputEventCount)
|
void CUI::InitInputs(IInput::CEvent *pInputEventsArray, int *pInputEventCount)
|
||||||
|
|
|
@ -131,15 +131,12 @@ protected:
|
||||||
CUI *UI() const { return m_pUI; }
|
CUI *UI() const { return m_pUI; }
|
||||||
std::vector<SUIElementRect> m_vUIRects;
|
std::vector<SUIElementRect> m_vUIRects;
|
||||||
|
|
||||||
// used for marquees or other user implemented things
|
|
||||||
int64_t m_ElementTime;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CUIElement() = default;
|
CUIElement() = default;
|
||||||
|
|
||||||
void Init(CUI *pUI, int RequestedRectCount);
|
void Init(CUI *pUI, int RequestedRectCount);
|
||||||
|
|
||||||
SUIElementRect *Get(size_t Index)
|
SUIElementRect *Rect(size_t Index)
|
||||||
{
|
{
|
||||||
return &m_vUIRects[Index];
|
return &m_vUIRects[Index];
|
||||||
}
|
}
|
||||||
|
@ -161,6 +158,21 @@ struct SLabelProperties
|
||||||
bool m_EnableWidthCheck = true;
|
bool m_EnableWidthCheck = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class CUIElementBase
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
static CUI *s_pUI;
|
||||||
|
|
||||||
|
public:
|
||||||
|
static void Init(CUI *pUI) { s_pUI = pUI; }
|
||||||
|
|
||||||
|
IClient *Client() const;
|
||||||
|
IGraphics *Graphics() const;
|
||||||
|
IInput *Input() const;
|
||||||
|
ITextRender *TextRender() const;
|
||||||
|
CUI *UI() const { return s_pUI; }
|
||||||
|
};
|
||||||
|
|
||||||
class CButtonContainer
|
class CButtonContainer
|
||||||
{
|
{
|
||||||
};
|
};
|
||||||
|
|
220
src/game/client/ui_scrollregion.cpp
Normal file
220
src/game/client/ui_scrollregion.cpp
Normal file
|
@ -0,0 +1,220 @@
|
||||||
|
/* (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. */
|
||||||
|
#include <base/system.h>
|
||||||
|
#include <base/vmath.h>
|
||||||
|
|
||||||
|
#include <engine/client.h>
|
||||||
|
#include <engine/keys.h>
|
||||||
|
|
||||||
|
#include "ui_scrollregion.h"
|
||||||
|
|
||||||
|
CScrollRegion::CScrollRegion()
|
||||||
|
{
|
||||||
|
m_ScrollY = 0.0f;
|
||||||
|
m_ContentH = 0.0f;
|
||||||
|
m_AnimTime = 0.0f;
|
||||||
|
m_AnimInitScrollY = 0.0f;
|
||||||
|
m_AnimTargetScrollY = 0.0f;
|
||||||
|
m_RequestScrollY = -1.0f;
|
||||||
|
m_ContentScrollOff = vec2(0.0f, 0.0f);
|
||||||
|
m_Params = CScrollRegionParams();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CScrollRegion::Begin(CUIRect *pClipRect, vec2 *pOutOffset, CScrollRegionParams *pParams)
|
||||||
|
{
|
||||||
|
if(pParams)
|
||||||
|
m_Params = *pParams;
|
||||||
|
|
||||||
|
const bool ContentOverflows = m_ContentH > pClipRect->h;
|
||||||
|
const bool ForceShowScrollbar = m_Params.m_Flags & CScrollRegionParams::FLAG_CONTENT_STATIC_WIDTH;
|
||||||
|
|
||||||
|
CUIRect ScrollBarBg;
|
||||||
|
bool HasScrollBar = ContentOverflows || ForceShowScrollbar;
|
||||||
|
CUIRect *pModifyRect = HasScrollBar ? pClipRect : nullptr;
|
||||||
|
pClipRect->VSplitRight(m_Params.m_ScrollbarWidth, pModifyRect, &ScrollBarBg);
|
||||||
|
ScrollBarBg.Margin(m_Params.m_ScrollbarMargin, &m_RailRect);
|
||||||
|
|
||||||
|
// only show scrollbar if required
|
||||||
|
if(HasScrollBar)
|
||||||
|
{
|
||||||
|
if(m_Params.m_ScrollbarBgColor.a > 0.0f)
|
||||||
|
ScrollBarBg.Draw(m_Params.m_ScrollbarBgColor, IGraphics::CORNER_R, 4.0f);
|
||||||
|
if(m_Params.m_RailBgColor.a > 0.0f)
|
||||||
|
m_RailRect.Draw(m_Params.m_RailBgColor, IGraphics::CORNER_ALL, m_RailRect.w / 2.0f);
|
||||||
|
}
|
||||||
|
if(!ContentOverflows)
|
||||||
|
m_ContentScrollOff.y = 0.0f;
|
||||||
|
|
||||||
|
if(m_Params.m_ClipBgColor.a > 0.0f)
|
||||||
|
pClipRect->Draw(m_Params.m_ClipBgColor, HasScrollBar ? IGraphics::CORNER_L : IGraphics::CORNER_ALL, 4.0f);
|
||||||
|
|
||||||
|
UI()->ClipEnable(pClipRect);
|
||||||
|
|
||||||
|
m_ClipRect = *pClipRect;
|
||||||
|
m_ContentH = 0.0f;
|
||||||
|
*pOutOffset = m_ContentScrollOff;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CScrollRegion::End()
|
||||||
|
{
|
||||||
|
UI()->ClipDisable();
|
||||||
|
|
||||||
|
// only show scrollbar if content overflows
|
||||||
|
if(m_ContentH <= m_ClipRect.h)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// scroll wheel
|
||||||
|
CUIRect RegionRect = m_ClipRect;
|
||||||
|
RegionRect.w += m_Params.m_ScrollbarWidth;
|
||||||
|
|
||||||
|
const float AnimationDuration = 0.5f;
|
||||||
|
|
||||||
|
if(UI()->Enabled() && UI()->MouseHovered(&RegionRect))
|
||||||
|
{
|
||||||
|
const bool IsPageScroll = Input()->KeyIsPressed(KEY_LALT) || Input()->KeyIsPressed(KEY_RALT);
|
||||||
|
const float ScrollUnit = IsPageScroll ? m_ClipRect.h : m_Params.m_ScrollUnit;
|
||||||
|
if(Input()->KeyPress(KEY_MOUSE_WHEEL_UP))
|
||||||
|
{
|
||||||
|
m_AnimTime = AnimationDuration;
|
||||||
|
m_AnimInitScrollY = m_ScrollY;
|
||||||
|
m_AnimTargetScrollY -= ScrollUnit;
|
||||||
|
}
|
||||||
|
else if(Input()->KeyPress(KEY_MOUSE_WHEEL_DOWN))
|
||||||
|
{
|
||||||
|
m_AnimTime = AnimationDuration;
|
||||||
|
m_AnimInitScrollY = m_ScrollY;
|
||||||
|
m_AnimTargetScrollY += ScrollUnit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const float SliderHeight = maximum(m_Params.m_SliderMinHeight, m_ClipRect.h / m_ContentH * m_RailRect.h);
|
||||||
|
|
||||||
|
CUIRect Slider = m_RailRect;
|
||||||
|
Slider.h = SliderHeight;
|
||||||
|
|
||||||
|
const float MaxSlider = m_RailRect.h - SliderHeight;
|
||||||
|
const float MaxScroll = m_ContentH - m_ClipRect.h;
|
||||||
|
|
||||||
|
if(m_RequestScrollY >= 0.0f)
|
||||||
|
{
|
||||||
|
m_AnimTargetScrollY = m_RequestScrollY;
|
||||||
|
m_AnimTime = 0.0f;
|
||||||
|
m_RequestScrollY = -1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_AnimTargetScrollY = clamp(m_AnimTargetScrollY, 0.0f, MaxScroll);
|
||||||
|
|
||||||
|
if(absolute(m_AnimInitScrollY - m_AnimTargetScrollY) < 0.5f)
|
||||||
|
m_AnimTime = 0.0f;
|
||||||
|
|
||||||
|
if(m_AnimTime > 0.0f)
|
||||||
|
{
|
||||||
|
m_AnimTime -= Client()->RenderFrameTime();
|
||||||
|
float AnimProgress = (1.0f - powf(m_AnimTime / AnimationDuration, 3.0f)); // cubic ease out
|
||||||
|
m_ScrollY = m_AnimInitScrollY + (m_AnimTargetScrollY - m_AnimInitScrollY) * AnimProgress;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_ScrollY = m_AnimTargetScrollY;
|
||||||
|
}
|
||||||
|
|
||||||
|
Slider.y += m_ScrollY / MaxScroll * MaxSlider;
|
||||||
|
|
||||||
|
bool Hovered = false;
|
||||||
|
bool Grabbed = false;
|
||||||
|
const void *pID = &m_ScrollY;
|
||||||
|
const bool InsideSlider = UI()->MouseHovered(&Slider);
|
||||||
|
const bool InsideRail = UI()->MouseHovered(&m_RailRect);
|
||||||
|
|
||||||
|
if(UI()->CheckActiveItem(pID) && UI()->MouseButton(0))
|
||||||
|
{
|
||||||
|
float MouseY = UI()->MouseY();
|
||||||
|
m_ScrollY += (MouseY - (Slider.y + m_SliderGrabPos.y)) / MaxSlider * MaxScroll;
|
||||||
|
m_SliderGrabPos.y = clamp(m_SliderGrabPos.y, 0.0f, SliderHeight);
|
||||||
|
m_AnimTargetScrollY = m_ScrollY;
|
||||||
|
m_AnimTime = 0.0f;
|
||||||
|
Grabbed = true;
|
||||||
|
}
|
||||||
|
else if(InsideSlider)
|
||||||
|
{
|
||||||
|
UI()->SetHotItem(pID);
|
||||||
|
|
||||||
|
if(!UI()->CheckActiveItem(pID) && UI()->MouseButtonClicked(0))
|
||||||
|
{
|
||||||
|
UI()->SetActiveItem(pID);
|
||||||
|
m_SliderGrabPos.y = UI()->MouseY() - Slider.y;
|
||||||
|
m_AnimTargetScrollY = m_ScrollY;
|
||||||
|
m_AnimTime = 0.0f;
|
||||||
|
}
|
||||||
|
Hovered = true;
|
||||||
|
}
|
||||||
|
else if(InsideRail && UI()->MouseButtonClicked(0))
|
||||||
|
{
|
||||||
|
m_ScrollY += (UI()->MouseY() - (Slider.y + Slider.h / 2.0f)) / MaxSlider * MaxScroll;
|
||||||
|
UI()->SetActiveItem(pID);
|
||||||
|
m_SliderGrabPos.y = Slider.h / 2.0f;
|
||||||
|
m_AnimTargetScrollY = m_ScrollY;
|
||||||
|
m_AnimTime = 0.0f;
|
||||||
|
Hovered = true;
|
||||||
|
}
|
||||||
|
else if(UI()->CheckActiveItem(pID) && !UI()->MouseButton(0))
|
||||||
|
{
|
||||||
|
UI()->SetActiveItem(nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_ScrollY = clamp(m_ScrollY, 0.0f, MaxScroll);
|
||||||
|
m_ContentScrollOff.y = -m_ScrollY;
|
||||||
|
|
||||||
|
Slider.Draw(m_Params.SliderColor(Grabbed, Hovered), IGraphics::CORNER_ALL, Slider.w / 2.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CScrollRegion::AddRect(const CUIRect &Rect, bool ShouldScrollHere)
|
||||||
|
{
|
||||||
|
m_LastAddedRect = Rect;
|
||||||
|
// Round up and add 1 to fix pixel clipping at the end of the scrolling area
|
||||||
|
m_ContentH = maximum(ceilf(Rect.y + Rect.h - (m_ClipRect.y + m_ContentScrollOff.y)) + 1.0f, m_ContentH);
|
||||||
|
if(ShouldScrollHere)
|
||||||
|
ScrollHere();
|
||||||
|
return !IsRectClipped(Rect);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CScrollRegion::ScrollHere(EScrollOption Option)
|
||||||
|
{
|
||||||
|
const float MinHeight = minimum(m_ClipRect.h, m_LastAddedRect.h);
|
||||||
|
const float TopScroll = m_LastAddedRect.y - (m_ClipRect.y + m_ContentScrollOff.y);
|
||||||
|
|
||||||
|
switch(Option)
|
||||||
|
{
|
||||||
|
case SCROLLHERE_TOP:
|
||||||
|
m_RequestScrollY = TopScroll;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SCROLLHERE_BOTTOM:
|
||||||
|
m_RequestScrollY = TopScroll - (m_ClipRect.h - MinHeight);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SCROLLHERE_KEEP_IN_VIEW:
|
||||||
|
default:
|
||||||
|
const float DeltaY = m_LastAddedRect.y - m_ClipRect.y;
|
||||||
|
if(DeltaY < 0)
|
||||||
|
m_RequestScrollY = TopScroll;
|
||||||
|
else if(DeltaY > (m_ClipRect.h - MinHeight))
|
||||||
|
m_RequestScrollY = TopScroll - (m_ClipRect.h - MinHeight);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CScrollRegion::IsRectClipped(const CUIRect &Rect) const
|
||||||
|
{
|
||||||
|
return (m_ClipRect.x > (Rect.x + Rect.w) || (m_ClipRect.x + m_ClipRect.w) < Rect.x || m_ClipRect.y > (Rect.y + Rect.h) || (m_ClipRect.y + m_ClipRect.h) < Rect.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CScrollRegion::IsScrollbarShown() const
|
||||||
|
{
|
||||||
|
return m_ContentH > m_ClipRect.h;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CScrollRegion::IsAnimating() const
|
||||||
|
{
|
||||||
|
return m_AnimTime > 0.0f;
|
||||||
|
}
|
123
src/game/client/ui_scrollregion.h
Normal file
123
src/game/client/ui_scrollregion.h
Normal file
|
@ -0,0 +1,123 @@
|
||||||
|
/* (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 GAME_CLIENT_UI_SCROLLREGION_H
|
||||||
|
#define GAME_CLIENT_UI_SCROLLREGION_H
|
||||||
|
|
||||||
|
#include "ui.h"
|
||||||
|
|
||||||
|
struct CScrollRegionParams
|
||||||
|
{
|
||||||
|
float m_ScrollbarWidth;
|
||||||
|
float m_ScrollbarMargin;
|
||||||
|
float m_SliderMinHeight;
|
||||||
|
float m_ScrollUnit;
|
||||||
|
ColorRGBA m_ClipBgColor;
|
||||||
|
ColorRGBA m_ScrollbarBgColor;
|
||||||
|
ColorRGBA m_RailBgColor;
|
||||||
|
ColorRGBA m_SliderColor;
|
||||||
|
ColorRGBA m_SliderColorHover;
|
||||||
|
ColorRGBA m_SliderColorGrabbed;
|
||||||
|
unsigned m_Flags;
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
FLAG_CONTENT_STATIC_WIDTH = 1 << 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
CScrollRegionParams()
|
||||||
|
{
|
||||||
|
m_ScrollbarWidth = 20.0f;
|
||||||
|
m_ScrollbarMargin = 5.0f;
|
||||||
|
m_SliderMinHeight = 25.0f;
|
||||||
|
m_ScrollUnit = 10.0f;
|
||||||
|
m_ClipBgColor = ColorRGBA(0.0f, 0.0f, 0.0f, 0.0f);
|
||||||
|
m_ScrollbarBgColor = ColorRGBA(0.0f, 0.0f, 0.0f, 0.0f);
|
||||||
|
m_RailBgColor = ColorRGBA(1.0f, 1.0f, 1.0f, 0.25f);
|
||||||
|
m_SliderColor = ColorRGBA(0.8f, 0.8f, 0.8f, 1.0f);
|
||||||
|
m_SliderColorHover = ColorRGBA(1.0f, 1.0f, 1.0f, 1.0f);
|
||||||
|
m_SliderColorGrabbed = ColorRGBA(0.9f, 0.9f, 0.9f, 1.0f);
|
||||||
|
m_Flags = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ColorRGBA SliderColor(bool Active, bool Hovered) const
|
||||||
|
{
|
||||||
|
if(Active)
|
||||||
|
return m_SliderColorGrabbed;
|
||||||
|
else if(Hovered)
|
||||||
|
return m_SliderColorHover;
|
||||||
|
return m_SliderColor;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Usage:
|
||||||
|
-- Initialization --
|
||||||
|
static CScrollRegion s_ScrollRegion;
|
||||||
|
vec2 ScrollOffset(0, 0);
|
||||||
|
s_ScrollRegion.Begin(&ScrollRegionRect, &ScrollOffset);
|
||||||
|
Content = ScrollRegionRect;
|
||||||
|
Content.y += ScrollOffset.y;
|
||||||
|
|
||||||
|
-- "Register" your content rects --
|
||||||
|
CUIRect Rect;
|
||||||
|
Content.HSplitTop(SomeValue, &Rect, &Content);
|
||||||
|
s_ScrollRegion.AddRect(Rect);
|
||||||
|
|
||||||
|
-- [Optional] Knowing if a rect is clipped --
|
||||||
|
s_ScrollRegion.IsRectClipped(Rect);
|
||||||
|
|
||||||
|
-- [Optional] Scroll to a rect (to the last added rect)--
|
||||||
|
...
|
||||||
|
s_ScrollRegion.AddRect(Rect);
|
||||||
|
s_ScrollRegion.ScrollHere(Option);
|
||||||
|
|
||||||
|
-- [Convenience] Add rect and check for visibility at the same time
|
||||||
|
if(s_ScrollRegion.AddRect(Rect))
|
||||||
|
// The rect is visible (not clipped)
|
||||||
|
|
||||||
|
-- [Convenience] Add rect and scroll to it if it's selected
|
||||||
|
if(s_ScrollRegion.AddRect(Rect, ScrollToSelection && IsSelected))
|
||||||
|
// The rect is visible (not clipped)
|
||||||
|
|
||||||
|
-- End --
|
||||||
|
s_ScrollRegion.End();
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Instances of CScrollRegion must be static, as member addresses are used as UI item IDs
|
||||||
|
class CScrollRegion : private CUIElementBase
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
float m_ScrollY;
|
||||||
|
float m_ContentH;
|
||||||
|
float m_RequestScrollY; // [0, ContentHeight]
|
||||||
|
|
||||||
|
float m_AnimTime;
|
||||||
|
float m_AnimInitScrollY;
|
||||||
|
float m_AnimTargetScrollY;
|
||||||
|
|
||||||
|
CUIRect m_ClipRect;
|
||||||
|
CUIRect m_RailRect;
|
||||||
|
CUIRect m_LastAddedRect; // saved for ScrollHere()
|
||||||
|
vec2 m_SliderGrabPos; // where did user grab the slider
|
||||||
|
vec2 m_ContentScrollOff;
|
||||||
|
CScrollRegionParams m_Params;
|
||||||
|
|
||||||
|
public:
|
||||||
|
enum EScrollOption
|
||||||
|
{
|
||||||
|
SCROLLHERE_KEEP_IN_VIEW = 0,
|
||||||
|
SCROLLHERE_TOP,
|
||||||
|
SCROLLHERE_BOTTOM,
|
||||||
|
};
|
||||||
|
|
||||||
|
CScrollRegion();
|
||||||
|
void Begin(CUIRect *pClipRect, vec2 *pOutOffset, CScrollRegionParams *pParams = nullptr);
|
||||||
|
void End();
|
||||||
|
bool AddRect(const CUIRect &Rect, bool ShouldScrollHere = false); // returns true if the added rect is visible (not clipped)
|
||||||
|
void ScrollHere(EScrollOption Option = SCROLLHERE_KEEP_IN_VIEW);
|
||||||
|
bool IsRectClipped(const CUIRect &Rect) const;
|
||||||
|
bool IsScrollbarShown() const;
|
||||||
|
bool IsAnimating() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
File diff suppressed because it is too large
Load diff
|
@ -11,6 +11,7 @@
|
||||||
#include <game/client/render.h>
|
#include <game/client/render.h>
|
||||||
#include <game/client/ui.h>
|
#include <game/client/ui.h>
|
||||||
#include <game/mapitems.h>
|
#include <game/mapitems.h>
|
||||||
|
#include <game/mapitems_ex.h>
|
||||||
|
|
||||||
#include <engine/editor.h>
|
#include <engine/editor.h>
|
||||||
#include <engine/graphics.h>
|
#include <engine/graphics.h>
|
||||||
|
@ -187,6 +188,8 @@ public:
|
||||||
|
|
||||||
int m_ParallaxX;
|
int m_ParallaxX;
|
||||||
int m_ParallaxY;
|
int m_ParallaxY;
|
||||||
|
int m_CustomParallaxZoom;
|
||||||
|
int m_ParallaxZoom;
|
||||||
|
|
||||||
int m_UseClipping;
|
int m_UseClipping;
|
||||||
int m_ClipX;
|
int m_ClipX;
|
||||||
|
@ -253,6 +256,12 @@ public:
|
||||||
}
|
}
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
|
void OnEdited()
|
||||||
|
{
|
||||||
|
if(!m_CustomParallaxZoom)
|
||||||
|
m_ParallaxZoom = GetParallaxZoomDefault(m_ParallaxX, m_ParallaxY);
|
||||||
|
}
|
||||||
|
|
||||||
void Clear()
|
void Clear()
|
||||||
{
|
{
|
||||||
m_vpLayers.clear();
|
m_vpLayers.clear();
|
||||||
|
@ -788,6 +797,7 @@ public:
|
||||||
|
|
||||||
m_GuiActive = true;
|
m_GuiActive = true;
|
||||||
m_ProofBorders = false;
|
m_ProofBorders = false;
|
||||||
|
m_PreviewZoom = false;
|
||||||
|
|
||||||
m_ShowTileInfo = false;
|
m_ShowTileInfo = false;
|
||||||
m_ShowDetail = true;
|
m_ShowDetail = true;
|
||||||
|
@ -962,6 +972,8 @@ public:
|
||||||
bool m_ShowMousePointer;
|
bool m_ShowMousePointer;
|
||||||
bool m_GuiActive;
|
bool m_GuiActive;
|
||||||
bool m_ProofBorders;
|
bool m_ProofBorders;
|
||||||
|
bool m_PreviewZoom;
|
||||||
|
float m_MouseWScale = 1.0f; // Mouse (i.e. UI) scale relative to the World (selected Group)
|
||||||
float m_MouseX = 0.0f;
|
float m_MouseX = 0.0f;
|
||||||
float m_MouseY = 0.0f;
|
float m_MouseY = 0.0f;
|
||||||
float m_MouseWorldX = 0.0f;
|
float m_MouseWorldX = 0.0f;
|
||||||
|
@ -1114,9 +1126,10 @@ public:
|
||||||
|
|
||||||
bool IsEnvelopeUsed(int EnvelopeIndex) const;
|
bool IsEnvelopeUsed(int EnvelopeIndex) const;
|
||||||
|
|
||||||
void RenderImages(CUIRect Toolbox, CUIRect View);
|
void RenderLayers(CUIRect LayersBox);
|
||||||
void RenderLayers(CUIRect Toolbox, CUIRect View);
|
void RenderImagesList(CUIRect Toolbox);
|
||||||
void RenderSounds(CUIRect Toolbox, CUIRect View);
|
void RenderSelectedImage(CUIRect View);
|
||||||
|
void RenderSounds(CUIRect Toolbox);
|
||||||
void RenderModebar(CUIRect View);
|
void RenderModebar(CUIRect View);
|
||||||
void RenderStatusbar(CUIRect View);
|
void RenderStatusbar(CUIRect View);
|
||||||
void RenderEnvelopeEditor(CUIRect View);
|
void RenderEnvelopeEditor(CUIRect View);
|
||||||
|
@ -1128,7 +1141,7 @@ public:
|
||||||
void AddFileDialogEntry(int Index, CUIRect *pView);
|
void AddFileDialogEntry(int Index, CUIRect *pView);
|
||||||
void SelectGameLayer();
|
void SelectGameLayer();
|
||||||
void SortImages();
|
void SortImages();
|
||||||
void SelectLayerByTile(float &Scroll);
|
bool SelectLayerByTile();
|
||||||
|
|
||||||
//Tile Numbers For Explanations - TODO: Add/Improve tiles and explanations
|
//Tile Numbers For Explanations - TODO: Add/Improve tiles and explanations
|
||||||
enum
|
enum
|
||||||
|
|
|
@ -184,6 +184,10 @@ int CEditorMap::Save(class IStorage *pStorage, const char *pFileName)
|
||||||
// save group name
|
// save group name
|
||||||
StrToInts(GItem.m_aName, sizeof(GItem.m_aName) / sizeof(int), pGroup->m_aName);
|
StrToInts(GItem.m_aName, sizeof(GItem.m_aName) / sizeof(int), pGroup->m_aName);
|
||||||
|
|
||||||
|
CMapItemGroupEx GItemEx;
|
||||||
|
GItemEx.m_Version = CMapItemGroupEx::CURRENT_VERSION;
|
||||||
|
GItemEx.m_ParallaxZoom = pGroup->m_ParallaxZoom;
|
||||||
|
|
||||||
for(const auto &pLayer : pGroup->m_vpLayers)
|
for(const auto &pLayer : pGroup->m_vpLayers)
|
||||||
{
|
{
|
||||||
if(pLayer->m_Type == LAYERTYPE_TILES)
|
if(pLayer->m_Type == LAYERTYPE_TILES)
|
||||||
|
@ -331,7 +335,9 @@ int CEditorMap::Save(class IStorage *pStorage, const char *pFileName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
df.AddItem(MAPITEMTYPE_GROUP, GroupCount++, sizeof(GItem), &GItem);
|
df.AddItem(MAPITEMTYPE_GROUP, GroupCount, sizeof(GItem), &GItem);
|
||||||
|
df.AddItem(MAPITEMTYPE_GROUP_EX, GroupCount, sizeof(GItemEx), &GItemEx);
|
||||||
|
GroupCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// save envelopes
|
// save envelopes
|
||||||
|
@ -581,9 +587,15 @@ int CEditorMap::Load(class IStorage *pStorage, const char *pFileName, int Storag
|
||||||
|
|
||||||
int Start, Num;
|
int Start, Num;
|
||||||
DataFile.GetType(MAPITEMTYPE_GROUP, &Start, &Num);
|
DataFile.GetType(MAPITEMTYPE_GROUP, &Start, &Num);
|
||||||
|
|
||||||
|
int StartEx, NumEx;
|
||||||
|
DataFile.GetType(MAPITEMTYPE_GROUP_EX, &StartEx, &NumEx);
|
||||||
for(int g = 0; g < Num; g++)
|
for(int g = 0; g < Num; g++)
|
||||||
{
|
{
|
||||||
CMapItemGroup *pGItem = (CMapItemGroup *)DataFile.GetItem(Start + g, nullptr, nullptr);
|
CMapItemGroup *pGItem = (CMapItemGroup *)DataFile.GetItem(Start + g, nullptr, nullptr);
|
||||||
|
CMapItemGroupEx *pGItemEx = nullptr;
|
||||||
|
if(NumEx)
|
||||||
|
pGItemEx = (CMapItemGroupEx *)DataFile.GetItem(StartEx + g, nullptr, nullptr);
|
||||||
|
|
||||||
if(pGItem->m_Version < 1 || pGItem->m_Version > CMapItemGroup::CURRENT_VERSION)
|
if(pGItem->m_Version < 1 || pGItem->m_Version > CMapItemGroup::CURRENT_VERSION)
|
||||||
continue;
|
continue;
|
||||||
|
@ -607,6 +619,9 @@ int CEditorMap::Load(class IStorage *pStorage, const char *pFileName, int Storag
|
||||||
if(pGItem->m_Version >= 3)
|
if(pGItem->m_Version >= 3)
|
||||||
IntsToStr(pGItem->m_aName, sizeof(pGroup->m_aName) / sizeof(int), pGroup->m_aName);
|
IntsToStr(pGItem->m_aName, sizeof(pGroup->m_aName) / sizeof(int), pGroup->m_aName);
|
||||||
|
|
||||||
|
pGroup->m_ParallaxZoom = GetParallaxZoom(pGItem, pGItemEx);
|
||||||
|
pGroup->m_CustomParallaxZoom = pGroup->m_ParallaxZoom != GetParallaxZoomDefault(pGroup->m_ParallaxX, pGroup->m_ParallaxY);
|
||||||
|
|
||||||
for(int l = 0; l < pGItem->m_NumLayers; l++)
|
for(int l = 0; l < pGItem->m_NumLayers; l++)
|
||||||
{
|
{
|
||||||
CLayer *pLayer = nullptr;
|
CLayer *pLayer = nullptr;
|
||||||
|
|
|
@ -10,6 +10,8 @@
|
||||||
#include <engine/shared/config.h>
|
#include <engine/shared/config.h>
|
||||||
#include <engine/storage.h>
|
#include <engine/storage.h>
|
||||||
|
|
||||||
|
#include <game/client/ui_scrollregion.h>
|
||||||
|
|
||||||
#include "editor.h"
|
#include "editor.h"
|
||||||
|
|
||||||
// popup menu handling
|
// popup menu handling
|
||||||
|
@ -320,6 +322,8 @@ int CEditor::PopupGroup(CEditor *pEditor, CUIRect View, void *pContext)
|
||||||
PROP_POS_Y,
|
PROP_POS_Y,
|
||||||
PROP_PARA_X,
|
PROP_PARA_X,
|
||||||
PROP_PARA_Y,
|
PROP_PARA_Y,
|
||||||
|
PROP_CUSTOM_ZOOM,
|
||||||
|
PROP_PARA_ZOOM,
|
||||||
PROP_USE_CLIPPING,
|
PROP_USE_CLIPPING,
|
||||||
PROP_CLIP_X,
|
PROP_CLIP_X,
|
||||||
PROP_CLIP_Y,
|
PROP_CLIP_Y,
|
||||||
|
@ -334,6 +338,8 @@ int CEditor::PopupGroup(CEditor *pEditor, CUIRect View, void *pContext)
|
||||||
{"Pos Y", -pEditor->m_Map.m_vpGroups[pEditor->m_SelectedGroup]->m_OffsetY, PROPTYPE_INT_SCROLL, -1000000, 1000000},
|
{"Pos Y", -pEditor->m_Map.m_vpGroups[pEditor->m_SelectedGroup]->m_OffsetY, PROPTYPE_INT_SCROLL, -1000000, 1000000},
|
||||||
{"Para X", pEditor->m_Map.m_vpGroups[pEditor->m_SelectedGroup]->m_ParallaxX, PROPTYPE_INT_SCROLL, -1000000, 1000000},
|
{"Para X", pEditor->m_Map.m_vpGroups[pEditor->m_SelectedGroup]->m_ParallaxX, PROPTYPE_INT_SCROLL, -1000000, 1000000},
|
||||||
{"Para Y", pEditor->m_Map.m_vpGroups[pEditor->m_SelectedGroup]->m_ParallaxY, PROPTYPE_INT_SCROLL, -1000000, 1000000},
|
{"Para Y", pEditor->m_Map.m_vpGroups[pEditor->m_SelectedGroup]->m_ParallaxY, PROPTYPE_INT_SCROLL, -1000000, 1000000},
|
||||||
|
{"Custom Zoom", pEditor->m_Map.m_vpGroups[pEditor->m_SelectedGroup]->m_CustomParallaxZoom, PROPTYPE_BOOL, 0, 1},
|
||||||
|
{"Para Zoom", pEditor->m_Map.m_vpGroups[pEditor->m_SelectedGroup]->m_ParallaxZoom, PROPTYPE_INT_SCROLL, -1000000, 1000000},
|
||||||
|
|
||||||
{"Use Clipping", pEditor->m_Map.m_vpGroups[pEditor->m_SelectedGroup]->m_UseClipping, PROPTYPE_BOOL, 0, 1},
|
{"Use Clipping", pEditor->m_Map.m_vpGroups[pEditor->m_SelectedGroup]->m_UseClipping, PROPTYPE_BOOL, 0, 1},
|
||||||
{"Clip X", pEditor->m_Map.m_vpGroups[pEditor->m_SelectedGroup]->m_ClipX, PROPTYPE_INT_SCROLL, -1000000, 1000000},
|
{"Clip X", pEditor->m_Map.m_vpGroups[pEditor->m_SelectedGroup]->m_ClipX, PROPTYPE_INT_SCROLL, -1000000, 1000000},
|
||||||
|
@ -364,6 +370,13 @@ int CEditor::PopupGroup(CEditor *pEditor, CUIRect View, void *pContext)
|
||||||
pEditor->m_Map.m_vpGroups[pEditor->m_SelectedGroup]->m_ParallaxX = NewVal;
|
pEditor->m_Map.m_vpGroups[pEditor->m_SelectedGroup]->m_ParallaxX = NewVal;
|
||||||
else if(Prop == PROP_PARA_Y)
|
else if(Prop == PROP_PARA_Y)
|
||||||
pEditor->m_Map.m_vpGroups[pEditor->m_SelectedGroup]->m_ParallaxY = NewVal;
|
pEditor->m_Map.m_vpGroups[pEditor->m_SelectedGroup]->m_ParallaxY = NewVal;
|
||||||
|
else if(Prop == PROP_CUSTOM_ZOOM)
|
||||||
|
pEditor->m_Map.m_vpGroups[pEditor->m_SelectedGroup]->m_CustomParallaxZoom = NewVal;
|
||||||
|
else if(Prop == PROP_PARA_ZOOM)
|
||||||
|
{
|
||||||
|
pEditor->m_Map.m_vpGroups[pEditor->m_SelectedGroup]->m_CustomParallaxZoom = 1;
|
||||||
|
pEditor->m_Map.m_vpGroups[pEditor->m_SelectedGroup]->m_ParallaxZoom = NewVal;
|
||||||
|
}
|
||||||
else if(Prop == PROP_POS_X)
|
else if(Prop == PROP_POS_X)
|
||||||
pEditor->m_Map.m_vpGroups[pEditor->m_SelectedGroup]->m_OffsetX = -NewVal;
|
pEditor->m_Map.m_vpGroups[pEditor->m_SelectedGroup]->m_OffsetX = -NewVal;
|
||||||
else if(Prop == PROP_POS_Y)
|
else if(Prop == PROP_POS_Y)
|
||||||
|
@ -378,6 +391,8 @@ int CEditor::PopupGroup(CEditor *pEditor, CUIRect View, void *pContext)
|
||||||
pEditor->m_Map.m_vpGroups[pEditor->m_SelectedGroup]->m_ClipW = NewVal;
|
pEditor->m_Map.m_vpGroups[pEditor->m_SelectedGroup]->m_ClipW = NewVal;
|
||||||
else if(Prop == PROP_CLIP_H)
|
else if(Prop == PROP_CLIP_H)
|
||||||
pEditor->m_Map.m_vpGroups[pEditor->m_SelectedGroup]->m_ClipH = NewVal;
|
pEditor->m_Map.m_vpGroups[pEditor->m_SelectedGroup]->m_ClipH = NewVal;
|
||||||
|
|
||||||
|
pEditor->m_Map.m_vpGroups[pEditor->m_SelectedGroup]->OnEdited();
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1234,54 +1249,29 @@ static int g_SelectImageCurrent = -100;
|
||||||
int CEditor::PopupSelectImage(CEditor *pEditor, CUIRect View, void *pContext)
|
int CEditor::PopupSelectImage(CEditor *pEditor, CUIRect View, void *pContext)
|
||||||
{
|
{
|
||||||
CUIRect ButtonBar, ImageView;
|
CUIRect ButtonBar, ImageView;
|
||||||
View.VSplitLeft(80.0f, &ButtonBar, &View);
|
View.VSplitLeft(150.0f, &ButtonBar, &View);
|
||||||
View.Margin(10.0f, &ImageView);
|
View.Margin(10.0f, &ImageView);
|
||||||
|
|
||||||
int ShowImage = g_SelectImageCurrent;
|
int ShowImage = g_SelectImageCurrent;
|
||||||
|
|
||||||
static float s_ScrollValue = 0;
|
const float RowHeight = 14.0f;
|
||||||
float ImagesHeight = pEditor->m_Map.m_vpImages.size() * 14;
|
static CScrollRegion s_ScrollRegion;
|
||||||
float ScrollDifference = ImagesHeight - ButtonBar.h;
|
vec2 ScrollOffset(0.0f, 0.0f);
|
||||||
|
CScrollRegionParams ScrollParams;
|
||||||
|
ScrollParams.m_ScrollbarWidth = 10.0f;
|
||||||
|
ScrollParams.m_ScrollbarMargin = 3.0f;
|
||||||
|
ScrollParams.m_ScrollUnit = RowHeight * 5;
|
||||||
|
s_ScrollRegion.Begin(&ButtonBar, &ScrollOffset, &ScrollParams);
|
||||||
|
ButtonBar.y += ScrollOffset.y;
|
||||||
|
|
||||||
if(pEditor->m_Map.m_vpImages.size() > 20) // Do we need a scrollbar?
|
|
||||||
{
|
|
||||||
CUIRect Scroll;
|
|
||||||
ButtonBar.VSplitRight(20.0f, &ButtonBar, &Scroll);
|
|
||||||
s_ScrollValue = pEditor->UI()->DoScrollbarV(&s_ScrollValue, &Scroll, s_ScrollValue);
|
|
||||||
|
|
||||||
if(pEditor->UI()->MouseInside(&Scroll) || pEditor->UI()->MouseInside(&ButtonBar))
|
|
||||||
{
|
|
||||||
int ScrollNum = (int)((ImagesHeight - ButtonBar.h) / 14.0f) + 1;
|
|
||||||
if(ScrollNum > 0)
|
|
||||||
{
|
|
||||||
if(pEditor->Input()->KeyPress(KEY_MOUSE_WHEEL_UP))
|
|
||||||
s_ScrollValue = clamp(s_ScrollValue - 1.0f / ScrollNum, 0.0f, 1.0f);
|
|
||||||
if(pEditor->Input()->KeyPress(KEY_MOUSE_WHEEL_DOWN))
|
|
||||||
s_ScrollValue = clamp(s_ScrollValue + 1.0f / ScrollNum, 0.0f, 1.0f);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
float ImageStartAt = ScrollDifference * s_ScrollValue;
|
|
||||||
if(ImageStartAt < 0.0f)
|
|
||||||
ImageStartAt = 0.0f;
|
|
||||||
|
|
||||||
float ImageStopAt = ImagesHeight - ScrollDifference * (1 - s_ScrollValue);
|
|
||||||
float ImageCur = 0.0f;
|
|
||||||
for(int i = -1; i < (int)pEditor->m_Map.m_vpImages.size(); i++)
|
for(int i = -1; i < (int)pEditor->m_Map.m_vpImages.size(); i++)
|
||||||
{
|
{
|
||||||
if(ImageCur > ImageStopAt)
|
|
||||||
break;
|
|
||||||
if(ImageCur < ImageStartAt)
|
|
||||||
{
|
|
||||||
ImageCur += 14.0f;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
ImageCur += 14.0f;
|
|
||||||
|
|
||||||
CUIRect Button;
|
CUIRect Button;
|
||||||
ButtonBar.HSplitTop(14.0f, &Button, &ButtonBar);
|
ButtonBar.HSplitTop(RowHeight, &Button, &ButtonBar);
|
||||||
|
if(!s_ScrollRegion.AddRect(Button))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
Button.HSplitTop(12.0f, &Button, 0);
|
||||||
if(pEditor->UI()->MouseInside(&Button))
|
if(pEditor->UI()->MouseInside(&Button))
|
||||||
ShowImage = i;
|
ShowImage = i;
|
||||||
|
|
||||||
|
@ -1298,6 +1288,8 @@ int CEditor::PopupSelectImage(CEditor *pEditor, CUIRect View, void *pContext)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
s_ScrollRegion.End();
|
||||||
|
|
||||||
if(ShowImage >= 0 && (size_t)ShowImage < pEditor->m_Map.m_vpImages.size())
|
if(ShowImage >= 0 && (size_t)ShowImage < pEditor->m_Map.m_vpImages.size())
|
||||||
{
|
{
|
||||||
if(ImageView.h < ImageView.w)
|
if(ImageView.h < ImageView.w)
|
||||||
|
@ -1325,7 +1317,7 @@ void CEditor::PopupSelectImageInvoke(int Current, float x, float y)
|
||||||
static int s_SelectImagePopupId = 0;
|
static int s_SelectImagePopupId = 0;
|
||||||
g_SelectImageSelected = -100;
|
g_SelectImageSelected = -100;
|
||||||
g_SelectImageCurrent = Current;
|
g_SelectImageCurrent = Current;
|
||||||
UiInvokePopupMenu(&s_SelectImagePopupId, 0, x, y, 400, 300, PopupSelectImage);
|
UiInvokePopupMenu(&s_SelectImagePopupId, 0, x, y, 450, 300, PopupSelectImage);
|
||||||
}
|
}
|
||||||
|
|
||||||
int CEditor::PopupSelectImageResult()
|
int CEditor::PopupSelectImageResult()
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#include "layers.h"
|
#include "layers.h"
|
||||||
|
|
||||||
#include "mapitems.h"
|
#include "mapitems.h"
|
||||||
|
#include "mapitems_ex.h"
|
||||||
|
|
||||||
#include <engine/map.h>
|
#include <engine/map.h>
|
||||||
|
|
||||||
|
@ -10,9 +11,12 @@ CLayers::CLayers()
|
||||||
{
|
{
|
||||||
m_GroupsNum = 0;
|
m_GroupsNum = 0;
|
||||||
m_GroupsStart = 0;
|
m_GroupsStart = 0;
|
||||||
|
m_GroupsExNum = 0;
|
||||||
|
m_GroupsExStart = 0;
|
||||||
m_LayersNum = 0;
|
m_LayersNum = 0;
|
||||||
m_LayersStart = 0;
|
m_LayersStart = 0;
|
||||||
m_pGameGroup = 0;
|
m_pGameGroup = 0;
|
||||||
|
m_pGameGroupEx = 0;
|
||||||
m_pGameLayer = 0;
|
m_pGameLayer = 0;
|
||||||
m_pMap = 0;
|
m_pMap = 0;
|
||||||
|
|
||||||
|
@ -27,6 +31,7 @@ void CLayers::Init(class IKernel *pKernel)
|
||||||
{
|
{
|
||||||
m_pMap = pKernel->RequestInterface<IMap>();
|
m_pMap = pKernel->RequestInterface<IMap>();
|
||||||
m_pMap->GetType(MAPITEMTYPE_GROUP, &m_GroupsStart, &m_GroupsNum);
|
m_pMap->GetType(MAPITEMTYPE_GROUP, &m_GroupsStart, &m_GroupsNum);
|
||||||
|
m_pMap->GetType(MAPITEMTYPE_GROUP_EX, &m_GroupsExStart, &m_GroupsExNum);
|
||||||
m_pMap->GetType(MAPITEMTYPE_LAYER, &m_LayersStart, &m_LayersNum);
|
m_pMap->GetType(MAPITEMTYPE_LAYER, &m_LayersStart, &m_LayersNum);
|
||||||
|
|
||||||
m_pTeleLayer = 0;
|
m_pTeleLayer = 0;
|
||||||
|
@ -38,6 +43,7 @@ void CLayers::Init(class IKernel *pKernel)
|
||||||
for(int g = 0; g < NumGroups(); g++)
|
for(int g = 0; g < NumGroups(); g++)
|
||||||
{
|
{
|
||||||
CMapItemGroup *pGroup = GetGroup(g);
|
CMapItemGroup *pGroup = GetGroup(g);
|
||||||
|
CMapItemGroupEx *pGroupEx = GetGroupEx(g);
|
||||||
for(int l = 0; l < pGroup->m_NumLayers; l++)
|
for(int l = 0; l < pGroup->m_NumLayers; l++)
|
||||||
{
|
{
|
||||||
CMapItemLayer *pLayer = GetLayer(pGroup->m_StartLayer + l);
|
CMapItemLayer *pLayer = GetLayer(pGroup->m_StartLayer + l);
|
||||||
|
@ -50,6 +56,7 @@ void CLayers::Init(class IKernel *pKernel)
|
||||||
{
|
{
|
||||||
m_pGameLayer = pTilemap;
|
m_pGameLayer = pTilemap;
|
||||||
m_pGameGroup = pGroup;
|
m_pGameGroup = pGroup;
|
||||||
|
m_pGameGroupEx = pGroupEx;
|
||||||
|
|
||||||
// make sure the game group has standard settings
|
// make sure the game group has standard settings
|
||||||
m_pGameGroup->m_OffsetX = 0;
|
m_pGameGroup->m_OffsetX = 0;
|
||||||
|
@ -66,6 +73,9 @@ void CLayers::Init(class IKernel *pKernel)
|
||||||
m_pGameGroup->m_ClipH = 0;
|
m_pGameGroup->m_ClipH = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(pGroupEx)
|
||||||
|
pGroupEx->m_ParallaxZoom = 100;
|
||||||
|
|
||||||
//break;
|
//break;
|
||||||
}
|
}
|
||||||
if(pTilemap->m_Flags & TILESLAYERFLAG_TELE)
|
if(pTilemap->m_Flags & TILESLAYERFLAG_TELE)
|
||||||
|
@ -119,6 +129,7 @@ void CLayers::InitBackground(class IMap *pMap)
|
||||||
{
|
{
|
||||||
m_pMap = pMap;
|
m_pMap = pMap;
|
||||||
m_pMap->GetType(MAPITEMTYPE_GROUP, &m_GroupsStart, &m_GroupsNum);
|
m_pMap->GetType(MAPITEMTYPE_GROUP, &m_GroupsStart, &m_GroupsNum);
|
||||||
|
m_pMap->GetType(MAPITEMTYPE_GROUP_EX, &m_GroupsExStart, &m_GroupsExNum);
|
||||||
m_pMap->GetType(MAPITEMTYPE_LAYER, &m_LayersStart, &m_LayersNum);
|
m_pMap->GetType(MAPITEMTYPE_LAYER, &m_LayersStart, &m_LayersNum);
|
||||||
|
|
||||||
//following is here to prevent crash using standard map as background
|
//following is here to prevent crash using standard map as background
|
||||||
|
@ -131,6 +142,7 @@ void CLayers::InitBackground(class IMap *pMap)
|
||||||
for(int g = 0; g < NumGroups(); g++)
|
for(int g = 0; g < NumGroups(); g++)
|
||||||
{
|
{
|
||||||
CMapItemGroup *pGroup = GetGroup(g);
|
CMapItemGroup *pGroup = GetGroup(g);
|
||||||
|
CMapItemGroupEx *pGroupEx = GetGroupEx(g);
|
||||||
for(int l = 0; l < pGroup->m_NumLayers; l++)
|
for(int l = 0; l < pGroup->m_NumLayers; l++)
|
||||||
{
|
{
|
||||||
CMapItemLayer *pLayer = GetLayer(pGroup->m_StartLayer + l);
|
CMapItemLayer *pLayer = GetLayer(pGroup->m_StartLayer + l);
|
||||||
|
@ -143,6 +155,7 @@ void CLayers::InitBackground(class IMap *pMap)
|
||||||
{
|
{
|
||||||
m_pGameLayer = pTilemap;
|
m_pGameLayer = pTilemap;
|
||||||
m_pGameGroup = pGroup;
|
m_pGameGroup = pGroup;
|
||||||
|
m_pGameGroupEx = pGroupEx;
|
||||||
|
|
||||||
// make sure the game group has standard settings
|
// make sure the game group has standard settings
|
||||||
m_pGameGroup->m_OffsetX = 0;
|
m_pGameGroup->m_OffsetX = 0;
|
||||||
|
@ -158,6 +171,10 @@ void CLayers::InitBackground(class IMap *pMap)
|
||||||
m_pGameGroup->m_ClipW = 0;
|
m_pGameGroup->m_ClipW = 0;
|
||||||
m_pGameGroup->m_ClipH = 0;
|
m_pGameGroup->m_ClipH = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(pGroupEx)
|
||||||
|
pGroupEx->m_ParallaxZoom = 100;
|
||||||
|
|
||||||
//We don't care about tile layers.
|
//We don't care about tile layers.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -206,6 +223,15 @@ CMapItemGroup *CLayers::GetGroup(int Index) const
|
||||||
return static_cast<CMapItemGroup *>(m_pMap->GetItem(m_GroupsStart + Index, 0, 0));
|
return static_cast<CMapItemGroup *>(m_pMap->GetItem(m_GroupsStart + Index, 0, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CMapItemGroupEx *CLayers::GetGroupEx(int Index) const
|
||||||
|
{
|
||||||
|
// Map doesn't have GroupEx items or GroupEx indexes don't match groups for some other reason. Lets turn them off completely to be safe.
|
||||||
|
if(m_GroupsExNum != m_GroupsNum)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
return static_cast<CMapItemGroupEx *>(m_pMap->GetItem(m_GroupsExStart + Index, 0, 0));
|
||||||
|
}
|
||||||
|
|
||||||
CMapItemLayer *CLayers::GetLayer(int Index) const
|
CMapItemLayer *CLayers::GetLayer(int Index) const
|
||||||
{
|
{
|
||||||
return static_cast<CMapItemLayer *>(m_pMap->GetItem(m_LayersStart + Index, 0, 0));
|
return static_cast<CMapItemLayer *>(m_pMap->GetItem(m_LayersStart + Index, 0, 0));
|
||||||
|
|
|
@ -7,6 +7,7 @@ class IKernel;
|
||||||
class IMap;
|
class IMap;
|
||||||
|
|
||||||
struct CMapItemGroup;
|
struct CMapItemGroup;
|
||||||
|
struct CMapItemGroupEx;
|
||||||
struct CMapItemLayer;
|
struct CMapItemLayer;
|
||||||
struct CMapItemLayerTilemap;
|
struct CMapItemLayerTilemap;
|
||||||
|
|
||||||
|
@ -14,9 +15,12 @@ class CLayers
|
||||||
{
|
{
|
||||||
int m_GroupsNum;
|
int m_GroupsNum;
|
||||||
int m_GroupsStart;
|
int m_GroupsStart;
|
||||||
|
int m_GroupsExNum;
|
||||||
|
int m_GroupsExStart;
|
||||||
int m_LayersNum;
|
int m_LayersNum;
|
||||||
int m_LayersStart;
|
int m_LayersStart;
|
||||||
CMapItemGroup *m_pGameGroup;
|
CMapItemGroup *m_pGameGroup;
|
||||||
|
CMapItemGroupEx *m_pGameGroupEx;
|
||||||
CMapItemLayerTilemap *m_pGameLayer;
|
CMapItemLayerTilemap *m_pGameLayer;
|
||||||
IMap *m_pMap;
|
IMap *m_pMap;
|
||||||
|
|
||||||
|
@ -30,8 +34,10 @@ public:
|
||||||
int NumLayers() const { return m_LayersNum; }
|
int NumLayers() const { return m_LayersNum; }
|
||||||
IMap *Map() const { return m_pMap; }
|
IMap *Map() const { return m_pMap; }
|
||||||
CMapItemGroup *GameGroup() const { return m_pGameGroup; }
|
CMapItemGroup *GameGroup() const { return m_pGameGroup; }
|
||||||
|
CMapItemGroupEx *GameGroupEx() const { return m_pGameGroupEx; }
|
||||||
CMapItemLayerTilemap *GameLayer() const { return m_pGameLayer; }
|
CMapItemLayerTilemap *GameLayer() const { return m_pGameLayer; }
|
||||||
CMapItemGroup *GetGroup(int Index) const;
|
CMapItemGroup *GetGroup(int Index) const;
|
||||||
|
CMapItemGroupEx *GetGroupEx(int Index) const;
|
||||||
CMapItemLayer *GetLayer(int Index) const;
|
CMapItemLayer *GetLayer(int Index) const;
|
||||||
|
|
||||||
// DDRace
|
// DDRace
|
||||||
|
|
|
@ -1,7 +1,21 @@
|
||||||
#include "mapitems_ex.h"
|
#include "mapitems_ex.h"
|
||||||
|
|
||||||
|
#include <base/math.h>
|
||||||
#include <engine/shared/uuid_manager.h>
|
#include <engine/shared/uuid_manager.h>
|
||||||
|
|
||||||
|
int GetParallaxZoom(const CMapItemGroup *pGroup, const CMapItemGroupEx *pGroupEx)
|
||||||
|
{
|
||||||
|
if(pGroupEx)
|
||||||
|
return pGroupEx->m_ParallaxZoom;
|
||||||
|
|
||||||
|
return GetParallaxZoomDefault(pGroup->m_ParallaxX, pGroup->m_ParallaxY);
|
||||||
|
}
|
||||||
|
|
||||||
|
int GetParallaxZoomDefault(int ParallaxX, int ParallaxY)
|
||||||
|
{
|
||||||
|
return clamp(maximum(ParallaxX, ParallaxY), 0, 100);
|
||||||
|
}
|
||||||
|
|
||||||
void RegisterMapItemTypeUuids(CUuidManager *pManager)
|
void RegisterMapItemTypeUuids(CUuidManager *pManager)
|
||||||
{
|
{
|
||||||
#define UUID(id, name) pManager->RegisterName(id, name);
|
#define UUID(id, name) pManager->RegisterName(id, name);
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
#define GAME_MAPITEMS_EX_H
|
#define GAME_MAPITEMS_EX_H
|
||||||
#include <game/generated/protocol.h>
|
#include <game/generated/protocol.h>
|
||||||
|
|
||||||
|
#include "mapitems.h"
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
__MAPITEMTYPE_UUID_HELPER = OFFSET_MAPITEMTYPE_UUID - 1,
|
__MAPITEMTYPE_UUID_HELPER = OFFSET_MAPITEMTYPE_UUID - 1,
|
||||||
|
@ -43,5 +45,23 @@ struct CMapItemAutoMapperConfig
|
||||||
int m_Flags;
|
int m_Flags;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct CMapItemGroupEx
|
||||||
|
{
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
CURRENT_VERSION = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
int m_Version;
|
||||||
|
|
||||||
|
// ItemGroup's perceived distance from camera when zooming. Similar to how
|
||||||
|
// Parallax{X,Y} works when camera is moving along the X and Y axes,
|
||||||
|
// this setting applies to camera moving closer or away (zooming in or out).
|
||||||
|
int m_ParallaxZoom;
|
||||||
|
};
|
||||||
|
|
||||||
|
int GetParallaxZoom(const CMapItemGroup *pGroup, const CMapItemGroupEx *pGroupEx);
|
||||||
|
int GetParallaxZoomDefault(int ParallaxX, int ParallaxY);
|
||||||
|
|
||||||
void RegisterMapItemTypeUuids(class CUuidManager *pManager);
|
void RegisterMapItemTypeUuids(class CUuidManager *pManager);
|
||||||
#endif // GAME_MAPITEMS_EX_H
|
#endif // GAME_MAPITEMS_EX_H
|
||||||
|
|
|
@ -2,3 +2,4 @@
|
||||||
|
|
||||||
UUID(MAPITEMTYPE_TEST, "mapitemtype-test@ddnet.tw")
|
UUID(MAPITEMTYPE_TEST, "mapitemtype-test@ddnet.tw")
|
||||||
UUID(MAPITEMTYPE_AUTOMAPPER_CONFIG, "mapitemtype-automapper-config@ddnet.tw")
|
UUID(MAPITEMTYPE_AUTOMAPPER_CONFIG, "mapitemtype-automapper-config@ddnet.tw")
|
||||||
|
UUID(MAPITEMTYPE_GROUP_EX, "mapitemtype-group@ddnet.tw")
|
||||||
|
|
Loading…
Reference in a new issue