enum NewsCategory
{
DLCS,
DLC_PROMO,
MISC_PROMO
}
class NewsCarousel extends ScriptedWidgetEventHandler
{
protected const int MAX_ARTICLES = 3;
protected const float ARTICLE_SWITCH_TIME = 3.0;
protected Widget m_Root;
protected ButtonWidget m_HotlinkButton;
protected RichTextWidget m_HotlinkButtonLabel;
protected ImageWidget m_Image;
protected TextWidget m_TitleText;
protected ButtonWidget m_NextPageBtn;
protected ButtonWidget m_PrevPageBtn;
protected ImageWidget m_NextPageBtnIcon;
protected ImageWidget m_PrevPageBtnIcon;
#ifdef PLATFORM_CONSOLE
protected ImageWidget m_NextPageBtnIconConsole;
protected ImageWidget m_PrevPageBtnIconConsole;
#endif
protected ref array<JsonDataNewsArticle> m_NewsArticles;
protected JsonDataNewsArticle m_CurrentArticle;
protected ModInfo m_CurrentModInfo;
protected int m_ArticleIndex;
protected ref Timer m_NewsSwitchTimer;
protected bool m_SwitchToNext = true;
#ifdef PLATFORM_CONSOLE
protected MainMenuConsole m_MainMenu;
#else
protected MainMenu m_MainMenu;
#endif
protected GridSpacerWidget m_GridSpacer;
protected ref AnimatedGridSpacer m_AnimatedSpacer;
protected EInputDeviceType m_CurrentInputDevice;
void NewsCarousel(Widget parent, UIScriptedMenu mainMenu)
{
m_Root = g_Game.GetWorkspace().CreateWidgets("gui/layouts/new_ui/news_carousel.layout", parent);
m_TitleText = TextWidget.Cast(m_Root.FindAnyWidget("nf_title"));
m_NextPageBtn = ButtonWidget.Cast(m_Root.FindAnyWidget("next_button"));
m_PrevPageBtn = ButtonWidget.Cast(m_Root.FindAnyWidget("prev_button"));
m_HotlinkButton = ButtonWidget.Cast(m_Root.FindAnyWidget("nf_hotlink_button"));
m_HotlinkButtonLabel = RichTextWidget.Cast(m_Root.FindAnyWidget("nf_hotlink_label"));
m_NextPageBtnIcon = ImageWidget.Cast(m_Root.FindAnyWidget("next_icon_pc"));
m_PrevPageBtnIcon = ImageWidget.Cast(m_Root.FindAnyWidget("prev_icon_pc"));
m_PrevPageBtnIcon.Show(false);
#ifdef PLATFORM_CONSOLE
m_NextPageBtnIconConsole = ImageWidget.Cast(m_Root.FindAnyWidget("next_icon_console"));
m_PrevPageBtnIconConsole = ImageWidget.Cast(m_Root.FindAnyWidget("prev_icon_console"));
#ifdef PLATFORM_XBOX
m_NextPageBtnIconConsole.LoadImageFile(0, "set:xbox_buttons image:DPAD_right");
m_PrevPageBtnIconConsole.LoadImageFile(0, "set:xbox_buttons image:DPAD_left");
#else
m_NextPageBtnIconConsole.LoadImageFile(0, "set:playstation_buttons image:DPAD_right");
m_PrevPageBtnIconConsole.LoadImageFile(0, "set:playstation_buttons image:DPAD_left");
#endif
#endif
#ifdef PLATFORM_CONSOLE
m_MainMenu = MainMenuConsole.Cast(mainMenu);
#else
m_MainMenu = MainMenu.Cast(mainMenu);
#endif
m_GridSpacer = GridSpacerWidget.Cast(m_Root.FindAnyWidget("nf_grid"));
m_HotlinkButtonLabel.SetText(GetButtonLabel("255, 255, 255, 255"));
m_Root.SetHandler(this);
UpdateCarouselInfo();
#ifdef PLATFORM_CONSOLE
if (g_Game.GetMission())
{
g_Game.GetMission().GetOnInputDeviceChanged().Insert(OnInputDeviceChanged);
}
#endif
OnInputDeviceChanged(g_Game.GetInput().GetCurrentInputDevice());
}
void ~NewsCarousel()
{
if (m_NewsSwitchTimer)
m_NewsSwitchTimer.Stop();
if (g_Game.GetMission())
{
g_Game.GetMission().GetOnInputDeviceChanged().Remove(OnInputDeviceChanged);
}
}
void Destroy()
{
m_Root.Unlink();
}
protected void SwitchNews()
{
if (m_SwitchToNext && m_ArticleIndex < m_NewsArticles.Count() - 1)
{
NextArticle();
if (m_ArticleIndex == m_NewsArticles.Count() - 1)
{
m_SwitchToNext = false;
}
}
if (!m_SwitchToNext && m_ArticleIndex > 0)
{
PreviousArticle();
if (m_ArticleIndex == 0)
{
m_SwitchToNext = true;
}
}
}
void ShowNewsCarousel(bool show)
{
if (show)
{
UpdateCarouselInfo();
}
m_Root.Show(show);
}
protected void UpdateCarouselInfo()
{
if (!m_NewsArticles)
m_NewsArticles = new array<JsonDataNewsArticle>;
else
m_NewsArticles.Clear();
JsonDataNewsList newsData = MainMenuData.GetNewsData();
if (!newsData)
return;
for (int i = 0; i < newsData.News.Count(); i++)
{
JsonDataNewsArticle article = newsData.News[i];
if (article)
{
ModInfo modInfo = MainMenuData.GetDLCModInfoByName(article.dlcName);
if (article.categoryID == NewsCategory.DLCS)
{
if (modInfo && !modInfo.GetIsOwned())
{
m_NewsArticles.Insert(article);
}
}
if (article.categoryID == NewsCategory.DLC_PROMO)
{
if (!modInfo || (modInfo && !modInfo.GetIsOwned()))
{
m_NewsArticles.Insert(article);
}
}
if (m_NewsArticles.Count() >= MAX_ARTICLES)
break;
}
}
int articlesCount = m_NewsArticles.Count();
if (articlesCount < MAX_ARTICLES)
{
if (articlesCount == 0)
{
m_Root.Show(false);
}
else
{
m_Root.Show(true);
if (articlesCount == 1)
{
Widget pageIndicators = m_Root.FindAnyWidget("nf_pages");
if (pageIndicators)
{
pageIndicators.Show(false);
}
#ifndef PLATFORM_CONSOLE
m_NextPageBtnIcon.Show(false);
#else
m_NextPageBtnIconConsole.Show(false);
#endif
}
// Color carousel page indicators or hide them if not needed
for (int j = 1; j <= MAX_ARTICLES; j++)
{
Widget w = m_Root.FindAnyWidget("page" + j);
if (!w)
break;
if (j > articlesCount)
{
w.Show(false);
}
}
}
}
if (!m_NewsSwitchTimer && articlesCount > 1)
{
m_NewsSwitchTimer = new Timer(CALL_CATEGORY_GUI);
m_NewsSwitchTimer.Run(ARTICLE_SWITCH_TIME, this, "SwitchNews", null, true);
}
if (!m_AnimatedSpacer)
{
int maxColums = (articlesCount - 1);
m_AnimatedSpacer = new AnimatedGridSpacer(m_GridSpacer, maxColums, 0.4, AnimatedGridSpacerEasingType.EASE_IN_OUT_QUART);
m_AnimatedSpacer.m_OnAnimationComplete.Insert(OnAnimationCompleted);
}
ShowPost(0);
}
protected void ShowPost(int index)
{
m_CurrentArticle = null;
m_CurrentModInfo = null;
if (index == 0 && m_NewsArticles.Count() == 0 || index > m_NewsArticles.Count() - 1)
return;
JsonDataNewsArticle article = m_NewsArticles[index];
if (!article)
{
ErrorEx(string.Format("Failed to get article for index %1", index), ErrorExSeverity.WARNING);
return;
}
m_CurrentArticle = article;
ModInfo modInfo = MainMenuData.GetDLCModInfoByName(article.dlcName);
if (modInfo)
{
m_CurrentModInfo = modInfo;
}
m_ArticleIndex = index;
m_TitleText.SetText(article.title);
ImageWidget imageW = ImageWidget.Cast(m_Root.FindAnyWidget("nf_image" + index));
if (imageW)
{
if (article.coverImage != "")
{
imageW.LoadImageFile(0, article.coverImage);
imageW.SetImage(0);
}
}
for (int i = 1; i <= MAX_ARTICLES; i++)
{
Widget w = m_Root.FindAnyWidget("page" + i);
if (!w)
break;
if ((i - 1) == index)
{
ColorHighlight(w);
}
else
{
ColorNormal(w);
}
}
}
void OnAnimationCompleted()
{
Widget focusW = GetWidgetUnderCursor();
if (!focusW || focusW && focusW != m_HotlinkButton)
{
m_HotlinkButtonLabel.SetText(GetButtonLabel("255, 255, 255, 255"));
}
else
{
m_HotlinkButtonLabel.SetText(GetButtonLabel("255, 0, 0, 255"));
}
}
protected void ColorHighlight(Widget w)
{
w.SetColor(ARGB(255, 255, 0, 0));
}
protected void ColorNormal(Widget w)
{
w.SetColor(ARGB(140, 0, 0, 0));
}
void OnClickNextArticle()
{
if (m_NewsSwitchTimer)
m_NewsSwitchTimer.Stop();
NextArticle();
if (m_NewsSwitchTimer)
m_NewsSwitchTimer.Run(3.0, this, "SwitchNews", null, true);
}
protected void NextArticle()
{
if (!m_AnimatedSpacer || m_AnimatedSpacer.IsAnimating())
return;
if (m_ArticleIndex < m_NewsArticles.Count() - 1)
{
m_ArticleIndex++;
ShowPost(m_ArticleIndex);
m_AnimatedSpacer.MoveRight();
}
bool showRight = m_ArticleIndex < m_NewsArticles.Count() - 1;
ShowArrowRight(showRight);
bool showLeft = m_ArticleIndex > 0;
ShowArrowLeft(showLeft);
}
void OnClickPreviousArticle()
{
if (m_NewsSwitchTimer)
m_NewsSwitchTimer.Stop();
PreviousArticle();
if (m_NewsSwitchTimer)
m_NewsSwitchTimer.Run(3.0, this, "SwitchNews", null, true);
}
protected void PreviousArticle()
{
if (!m_AnimatedSpacer || m_AnimatedSpacer.IsAnimating())
return;
if (m_ArticleIndex > 0)
{
m_ArticleIndex--;
ShowPost(m_ArticleIndex);
m_AnimatedSpacer.MoveLeft();
}
bool showRight = m_ArticleIndex < m_NewsArticles.Count() - 1;
ShowArrowRight(showRight);
bool showLeft = m_ArticleIndex > 0;
ShowArrowLeft(showLeft);
}
protected void ShowArrowRight(bool state)
{
switch (m_CurrentInputDevice)
{
#ifdef PLATFORM_CONSOLE
case EInputDeviceType.CONTROLLER:
{
m_NextPageBtnIconConsole.Show(state);
break;
}
#endif
default:
{
if (g_Game.GetInput().IsEnabledMouseAndKeyboard())
{
m_NextPageBtnIcon.Show(state);
}
break;
}
}
}
protected void ShowArrowLeft(bool state)
{
switch (m_CurrentInputDevice)
{
#ifdef PLATFORM_CONSOLE
case EInputDeviceType.CONTROLLER:
{
m_PrevPageBtnIconConsole.Show(state);
break;
}
#endif
default:
{
if (g_Game.GetInput().IsEnabledMouseAndKeyboard())
{
m_PrevPageBtnIcon.Show(state);
}
break;
}
}
}
void ShowPromotion()
{
JsonDataNewsArticle article = m_NewsArticles[m_ArticleIndex];
if (!article)
{
ErrorEx(string.Format("Failed to get article for index %1", m_ArticleIndex), ErrorExSeverity.WARNING);
return;
}
if (m_CurrentModInfo)
{
m_CurrentModInfo.GoToStore();
}
else
{
if (article.fullUrl != "")
{
g_Game.OpenURL(article.fullUrl);
}
}
}
override bool OnClick(Widget w, int x, int y, int button)
{
if (w == m_HotlinkButton)
{
ShowPromotion();
}
else if (w == m_NextPageBtn)
{
OnClickNextArticle();
}
else if (w == m_PrevPageBtn)
{
OnClickPreviousArticle();
}
return false;
}
override bool OnMouseEnter(Widget w, int x, int y)
{
if (w == m_HotlinkButton)
{
if (m_CurrentArticle && m_CurrentArticle.fullUrl == string.Empty)
return false;
m_HotlinkButtonLabel.SetText(GetButtonLabel("255, 0, 0, 255"));
m_HotlinkButtonLabel.SetColor(ARGB(255, 255, 0, 0));
return true;
}
else if (w == m_NextPageBtn)
{
m_NextPageBtnIcon.SetColor(ARGB(255, 255, 0, 0));
return true;
}
else if (w == m_PrevPageBtn)
{
m_PrevPageBtnIcon.SetColor(ARGB(255, 255, 0, 0));
return true;
}
return false;
}
override bool OnMouseLeave(Widget w, Widget enterW, int x, int y)
{
if (w == m_HotlinkButton)
{
if (m_CurrentArticle && m_CurrentArticle.fullUrl == string.Empty)
return false;
m_HotlinkButtonLabel.SetText(GetButtonLabel("255, 255, 255, 255"));
m_HotlinkButtonLabel.SetColor(ARGB(255, 255, 255, 255));
return true;
}
else if (w == m_NextPageBtn)
{
m_NextPageBtnIcon.SetColor(ARGB(255, 255, 255, 255));
return true;
}
else if (w == m_PrevPageBtn)
{
m_PrevPageBtnIcon.SetColor(ARGB(255, 255, 255, 255));
return true;
}
return false;
}
protected void OnInputDeviceChanged(EInputDeviceType pInputDeviceType)
{
bool showNext = m_ArticleIndex < m_NewsArticles.Count() - 1;
bool showPrevious = m_ArticleIndex > 0;
if (pInputDeviceType == EInputDeviceType.UNKNOWN && g_Game.GetInput().IsActiveGamepadSelected())
pInputDeviceType = EInputDeviceType.CONTROLLER;
switch (pInputDeviceType)
{
case EInputDeviceType.CONTROLLER:
{
m_CurrentInputDevice = pInputDeviceType;
m_HotlinkButtonLabel.SetText(GetButtonLabel("255, 255, 255, 255"));
m_NextPageBtnIcon.Show(false);
m_PrevPageBtnIcon.Show(false);
#ifdef PLATFORM_CONSOLE
m_NextPageBtnIconConsole.Show(showNext);
m_PrevPageBtnIconConsole.Show(showPrevious);
#endif
break;
}
default:
{
if (g_Game.GetInput().IsEnabledMouseAndKeyboard())
{
m_CurrentInputDevice = pInputDeviceType;
m_HotlinkButtonLabel.SetText(GetButtonLabel("255, 255, 255, 255"));
#ifdef PLATFORM_CONSOLE
m_NextPageBtnIconConsole.Show(false);
m_PrevPageBtnIconConsole.Show(false);
#endif
m_NextPageBtnIcon.Show(showNext);
m_PrevPageBtnIcon.Show(showPrevious);
break;
}
}
}
}
protected string GetButtonLabel(string color)
{
string shopLabel;
#ifdef PLATFORM_WINDOWS
shopLabel = "#dlc_open_store";
#endif
#ifdef PLATFORM_CONSOLE
#ifdef PLATFORM_MSSTORE
shopLabel = "#dlc_open_store_Xbox";
#else
#ifdef PLATFORM_XBOX
shopLabel = "#dlc_open_store_Xbox";
#else
shopLabel = "#dlc_open_store_PS";
#endif
#endif
#endif
if (m_CurrentArticle)
{
switch (m_CurrentArticle.categoryID)
{
case NewsCategory.DLC_PROMO:
{
if (m_CurrentArticle.fullUrl != string.Empty)
{
shopLabel = "#dlc_news_wishlist";
}
else
{
shopLabel = "#dlc_news_comingsoon";
}
break;
}
case NewsCategory.MISC_PROMO:
{
shopLabel = "#dlc_news_learn_more";
break;
}
}
}
string label = shopLabel;
string linkIcon = string.Format("<image set=\"%1\" name=\"%2\" scale=\"%3\"/>", "dayz_gui", "externallink", 0.9);
if (m_CurrentInputDevice == EInputDeviceType.CONTROLLER && m_CurrentArticle && m_CurrentArticle.fullUrl != string.Empty)
{
label = string.Format("#dlc_news_hold %1%2", InputUtils.GetRichtextButtonIconFromInputAction("UAUICtrlX", "", EUAINPUT_DEVICE_CONTROLLER, 1.2), shopLabel);
}
string fullLabel = string.Format("<color rgba=\"%1\">%2 %3</color>", color, label, linkIcon);
if (m_CurrentArticle && m_CurrentArticle.fullUrl == string.Empty)
fullLabel = string.Format("<color rgba=\"%1\">%2</color>", color, label);
return fullLabel;
}
void Update(float timeslice)
{
if (m_AnimatedSpacer)
m_AnimatedSpacer.Update(timeslice);
}
}