Codechange: Use std::list for News Items. (#12338)

This commit is contained in:
Peter Nelson 2024-04-04 07:53:14 +01:00 committed by GitHub
parent 08cf106fc6
commit f6a88e40a4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 155 additions and 196 deletions

View File

@ -56,11 +56,12 @@ static void SurveyRecentNews(nlohmann::json &json)
json = nlohmann::json::array();
int i = 0;
for (NewsItem *news = _latest_news; i < 32 && news != nullptr; news = news->prev, i++) {
TimerGameCalendar::YearMonthDay ymd = TimerGameCalendar::ConvertDateToYMD(news->date);
for (const auto &news : GetNews()) {
TimerGameCalendar::YearMonthDay ymd = TimerGameCalendar::ConvertDateToYMD(news.date);
json.push_back(fmt::format("({}-{:02}-{:02}) StringID: {}, Type: {}, Ref1: {}, {}, Ref2: {}, {}",
ymd.year, ymd.month + 1, ymd.day, news->string_id, news->type,
news->reftype1, news->ref1, news->reftype2, news->ref2));
ymd.year, ymd.month + 1, ymd.day, news.string_id, news.type,
news.reftype1, news.ref1, news.reftype2, news.ref2));
if (++i > 32) break;
}
}

View File

@ -55,7 +55,7 @@ inline void AddIndustryNewsItem(StringID string, NewsType type, IndustryID indus
void NewsLoop();
void InitNewsItemStructs();
extern const NewsItem *_statusbar_news_item;
const NewsItem *GetStatusbarNews();
void DeleteInvalidEngineNews();
void DeleteVehicleNews(VehicleID vid, StringID news);

View File

@ -21,7 +21,6 @@
#include "town.h"
#include "sound_func.h"
#include "string_func.h"
#include "dropdown_func.h"
#include "statusbar_gui.h"
#include "company_manager_face.h"
#include "company_func.h"
@ -44,25 +43,42 @@
#include "safeguards.h"
const NewsItem *_statusbar_news_item = nullptr;
static const uint MIN_NEWS_AMOUNT = 30; ///< preferred minimum amount of news messages.
static const uint MAX_NEWS_AMOUNT = 1U << 10; ///< Do not exceed this number of news messages.
static uint MIN_NEWS_AMOUNT = 30; ///< preferred minimum amount of news messages
static uint MAX_NEWS_AMOUNT = 1 << 10; ///< Do not exceed this number of news messages
static uint _total_news = 0; ///< current number of news items
static NewsItem *_oldest_news = nullptr; ///< head of news items queue
NewsItem *_latest_news = nullptr; ///< tail of news items queue
static NewsContainer _news; ///< List of news, with newest items at the start.
/**
* Forced news item.
* Users can force an item by accessing the history or "last message".
* If the message being shown was forced by the user, a pointer is stored
* in _forced_news. Otherwise, \a _forced_news variable is nullptr.
* If the message being shown was forced by the user, an iterater is stored
* in _forced_news. Otherwise, \a _forced_news variable is the end of \a _news.
*/
static const NewsItem *_forced_news = nullptr;
static NewsIterator _forced_news = std::end(_news);
/** Current news item (last item shown regularly). */
static const NewsItem *_current_news = nullptr;
static NewsIterator _current_news = std::end(_news);
/** Current status bar news item. */
static NewsIterator _statusbar_news = std::end(_news);
/**
* Get pointer to the current status bar news item.
* @return Pointer to the current status bar news item, or nullptr if there is none.
*/
const NewsItem *GetStatusbarNews()
{
return (_statusbar_news == std::end(_news)) ? nullptr : &*_statusbar_news;
}
/**
* Get read-only reference to all news items.
* @return Read-only reference to all news items.
*/
const NewsContainer &GetNews()
{
return _news;
}
/**
* Get the position a news-reference is referencing.
@ -484,7 +500,7 @@ struct NewsWindow : Window {
case WID_N_CLOSEBOX:
NewsWindow::duration = 0;
this->Close();
_forced_news = nullptr;
_forced_news = std::end(_news);
break;
case WID_N_CAPTION:
@ -622,29 +638,21 @@ static void ShowNewspaper(const NewsItem *ni)
}
/** Show news item in the ticker */
static void ShowTicker(const NewsItem *ni)
static void ShowTicker(NewsIterator ni)
{
if (_settings_client.sound.news_ticker) SndPlayFx(SND_16_NEWS_TICKER);
_statusbar_news_item = ni;
_statusbar_news = ni;
InvalidateWindowData(WC_STATUS_BAR, 0, SBI_SHOW_TICKER);
}
/** Initialize the news-items data structures */
void InitNewsItemStructs()
{
for (NewsItem *ni = _oldest_news; ni != nullptr; ) {
NewsItem *next = ni->next;
delete ni;
ni = next;
}
_total_news = 0;
_oldest_news = nullptr;
_latest_news = nullptr;
_forced_news = nullptr;
_current_news = nullptr;
_statusbar_news_item = nullptr;
_news.clear();
_forced_news = std::end(_news);
_current_news = std::end(_news);
_statusbar_news = std::end(_news);
NewsWindow::duration = 0;
}
@ -654,7 +662,7 @@ void InitNewsItemStructs()
*/
static bool ReadyForNextTickerItem()
{
const NewsItem *ni = _statusbar_news_item;
const NewsItem *ni = GetStatusbarNews();
if (ni == nullptr) return true;
/* Ticker message
@ -668,8 +676,7 @@ static bool ReadyForNextTickerItem()
*/
static bool ReadyForNextNewsItem()
{
const NewsItem *ni = _forced_news == nullptr ? _current_news : _forced_news;
if (ni == nullptr) return true;
if (_forced_news == std::end(_news) && _current_news == std::end(_news)) return true;
/* neither newsticker nor newspaper are running */
return (NewsWindow::duration <= 0 || FindWindowById(WC_NEWS_WINDOW, 0) == nullptr);
@ -678,116 +685,98 @@ static bool ReadyForNextNewsItem()
/** Move to the next ticker item */
static void MoveToNextTickerItem()
{
assert(!std::empty(_news));
/* There is no status bar, so no reason to show news;
* especially important with the end game screen when
* there is no status bar but possible news. */
if (FindWindowById(WC_STATUS_BAR, 0) == nullptr) return;
/* if we're not at the last item, then move on */
while (_statusbar_news_item != _latest_news) {
_statusbar_news_item = (_statusbar_news_item == nullptr) ? _oldest_news : _statusbar_news_item->next;
const NewsItem *ni = _statusbar_news_item;
const NewsType type = ni->type;
/* if we're not at the latest item, then move on */
while (_statusbar_news != std::begin(_news)) {
--_statusbar_news;
const NewsType type = _statusbar_news->type;
/* check the date, don't show too old items */
if (TimerGameEconomy::date - _news_type_data[type].age > ni->economy_date) continue;
if (TimerGameEconomy::date - _news_type_data[type].age > _statusbar_news->economy_date) continue;
switch (_news_type_data[type].GetDisplay()) {
default: NOT_REACHED();
case ND_OFF: // Off - show nothing only a small reminder in the status bar
InvalidateWindowData(WC_STATUS_BAR, 0, SBI_SHOW_REMINDER);
break;
return;
case ND_SUMMARY: // Summary - show ticker
ShowTicker(ni);
break;
ShowTicker(_statusbar_news);
return;
case ND_FULL: // Full - show newspaper, skipped here
continue;
break;;
}
return;
}
}
/** Move to the next news item */
static void MoveToNextNewsItem()
{
assert(!std::empty(_news));
/* There is no status bar, so no reason to show news;
* especially important with the end game screen when
* there is no status bar but possible news. */
if (FindWindowById(WC_STATUS_BAR, 0) == nullptr) return;
CloseWindowById(WC_NEWS_WINDOW, 0); // close the newspapers window if shown
_forced_news = nullptr;
_forced_news = std::end(_news);
/* if we're not at the last item, then move on */
while (_current_news != _latest_news) {
_current_news = (_current_news == nullptr) ? _oldest_news : _current_news->next;
const NewsItem *ni = _current_news;
const NewsType type = ni->type;
/* if we're not at the latest item, then move on */
while (_current_news != std::begin(_news)) {
--_current_news;
const NewsType type = _current_news->type;
/* check the date, don't show too old items */
if (TimerGameEconomy::date - _news_type_data[type].age > ni->economy_date) continue;
if (TimerGameEconomy::date - _news_type_data[type].age > _current_news->economy_date) continue;
switch (_news_type_data[type].GetDisplay()) {
default: NOT_REACHED();
case ND_OFF: // Off - show nothing only a small reminder in the status bar, skipped here
continue;
break;
case ND_SUMMARY: // Summary - show ticker, skipped here
continue;
break;;
case ND_FULL: // Full - show newspaper
ShowNewspaper(ni);
break;
ShowNewspaper(&*_current_news);
return;
}
return;
}
}
/** Delete a news item from the queue */
static void DeleteNewsItem(NewsItem *ni)
static std::list<NewsItem>::iterator DeleteNewsItem(std::list<NewsItem>::iterator ni)
{
/* Delete the news from the news queue. */
if (ni->prev != nullptr) {
ni->prev->next = ni->next;
} else {
assert(_oldest_news == ni);
_oldest_news = ni->next;
}
if (ni->next != nullptr) {
ni->next->prev = ni->prev;
} else {
assert(_latest_news == ni);
_latest_news = ni->prev;
}
_total_news--;
if (_forced_news == ni || _current_news == ni) {
/* When we're the current news, go to the previous item first;
* we just possibly made that the last news item. */
if (_current_news == ni) _current_news = ni->prev;
if (_current_news == ni) _current_news = (_current_news == std::begin(_news)) ? std::end(_news) : std::prev(_current_news);
/* About to remove the currently forced item (shown as newspapers) ||
* about to remove the currently displayed item (newspapers) */
MoveToNextNewsItem();
}
if (_statusbar_news_item == ni) {
if (_statusbar_news == ni) {
/* When we're the current news, go to the previous item first;
* we just possibly made that the last news item. */
_statusbar_news_item = ni->prev;
if (_statusbar_news == ni) _statusbar_news = (_statusbar_news == std::begin(_news)) ? std::end(_news) : std::prev(_statusbar_news);
/* About to remove the currently displayed item (ticker, or just a reminder) */
InvalidateWindowData(WC_STATUS_BAR, 0, SBI_NEWS_DELETED); // invalidate the statusbar
MoveToNextTickerItem();
}
delete ni;
SetWindowDirty(WC_MESSAGE_HISTORY, 0);
/* Delete the news from the news queue. */
return _news.erase(ni);
}
/**
@ -829,27 +818,14 @@ void AddNewsItem(StringID string, NewsType type, NewsFlag flags, NewsReferenceTy
if (_game_mode == GM_MENU) return;
/* Create new news item node */
NewsItem *ni = new NewsItem(string, type, flags, reftype1, ref1, reftype2, ref2, data);
if (_total_news++ == 0) {
assert(_oldest_news == nullptr);
_oldest_news = ni;
ni->prev = nullptr;
} else {
assert(_latest_news->next == nullptr);
_latest_news->next = ni;
ni->prev = _latest_news;
}
ni->next = nullptr;
_latest_news = ni;
_news.emplace_front(string, type, flags, reftype1, ref1, reftype2, ref2, data);
/* Keep the number of stored news items to a managable number */
if (_total_news > MAX_NEWS_AMOUNT) {
DeleteNewsItem(_oldest_news);
if (std::size(_news) > MAX_NEWS_AMOUNT) {
DeleteNewsItem(std::prev(std::end(_news)));
}
SetWindowDirty(WC_MESSAGE_HISTORY, 0);
InvalidateWindowData(WC_MESSAGE_HISTORY, 0);
}
/**
@ -910,6 +886,29 @@ CommandCost CmdCustomNewsItem(DoCommandFlag flags, NewsType type, NewsReferenceT
return CommandCost();
}
/**
* Delete news items by predicate, and invalidate the message history if necessary.
* @tparam Tmin Stop if the number of news items remaining reaches \a min items.
* @tparam Tpredicate Condition for a news item to be deleted.
*/
template <size_t Tmin = 0, class Tpredicate>
void DeleteNews(Tpredicate predicate)
{
bool dirty = false;
for (auto it = std::rbegin(_news); it != std::rend(_news); /* nothing */) {
if constexpr (Tmin > 0) {
if (std::size(_news) <= Tmin) break;
}
if (predicate(*it)) {
it = std::make_reverse_iterator(DeleteNewsItem(std::prev(it.base())));
dirty = true;
} else {
++it;
}
}
if (dirty) InvalidateWindowData(WC_MESSAGE_HISTORY, 0);
}
/**
* Delete a news item type about a vehicle.
* When the news item type is INVALID_STRING_ID all news about the vehicle gets deleted.
@ -918,16 +917,9 @@ CommandCost CmdCustomNewsItem(DoCommandFlag flags, NewsType type, NewsReferenceT
*/
void DeleteVehicleNews(VehicleID vid, StringID news)
{
NewsItem *ni = _oldest_news;
while (ni != nullptr) {
NewsItem *next = ni->next;
if (((ni->reftype1 == NR_VEHICLE && ni->ref1 == vid) || (ni->reftype2 == NR_VEHICLE && ni->ref2 == vid)) &&
(news == INVALID_STRING_ID || ni->string_id == news)) {
DeleteNewsItem(ni);
}
ni = next;
}
DeleteNews([&](const auto &ni) {
return ((ni.reftype1 == NR_VEHICLE && ni.ref1 == vid) || (ni.reftype2 == NR_VEHICLE && ni.ref2 == vid)) && (news == INVALID_STRING_ID || ni.string_id == news);
});
}
/**
@ -937,15 +929,9 @@ void DeleteVehicleNews(VehicleID vid, StringID news)
*/
void DeleteStationNews(StationID sid)
{
NewsItem *ni = _oldest_news;
while (ni != nullptr) {
NewsItem *next = ni->next;
if ((ni->reftype1 == NR_STATION && ni->ref1 == sid) || (ni->reftype2 == NR_STATION && ni->ref2 == sid)) {
DeleteNewsItem(ni);
}
ni = next;
}
DeleteNews([&](const auto &ni) {
return (ni.reftype1 == NR_STATION && ni.ref1 == sid) || (ni.reftype2 == NR_STATION && ni.ref2 == sid);
});
}
/**
@ -954,15 +940,9 @@ void DeleteStationNews(StationID sid)
*/
void DeleteIndustryNews(IndustryID iid)
{
NewsItem *ni = _oldest_news;
while (ni != nullptr) {
NewsItem *next = ni->next;
if ((ni->reftype1 == NR_INDUSTRY && ni->ref1 == iid) || (ni->reftype2 == NR_INDUSTRY && ni->ref2 == iid)) {
DeleteNewsItem(ni);
}
ni = next;
}
DeleteNews([&](const auto &ni) {
return (ni.reftype1 == NR_INDUSTRY && ni.ref1 == iid) || (ni.reftype2 == NR_INDUSTRY && ni.ref2 == iid);
});
}
/**
@ -970,25 +950,17 @@ void DeleteIndustryNews(IndustryID iid)
*/
void DeleteInvalidEngineNews()
{
NewsItem *ni = _oldest_news;
while (ni != nullptr) {
NewsItem *next = ni->next;
if ((ni->reftype1 == NR_ENGINE && (!Engine::IsValidID(ni->ref1) || !Engine::Get(ni->ref1)->IsEnabled())) ||
(ni->reftype2 == NR_ENGINE && (!Engine::IsValidID(ni->ref2) || !Engine::Get(ni->ref2)->IsEnabled()))) {
DeleteNewsItem(ni);
}
ni = next;
}
DeleteNews([](const auto &ni) {
return (ni.reftype1 == NR_ENGINE && (!Engine::IsValidID(ni.ref1) || !Engine::Get(ni.ref1)->IsEnabled())) ||
(ni.reftype2 == NR_ENGINE && (!Engine::IsValidID(ni.ref2) || !Engine::Get(ni.ref2)->IsEnabled()));
});
}
static void RemoveOldNewsItems()
{
NewsItem *next;
for (NewsItem *cur = _oldest_news; _total_news > MIN_NEWS_AMOUNT && cur != nullptr; cur = next) {
next = cur->next;
if (TimerGameEconomy::date - _news_type_data[cur->type].age * _settings_client.gui.news_message_timeout > cur->economy_date) DeleteNewsItem(cur);
}
DeleteNews<MIN_NEWS_AMOUNT>([](const auto &ni) {
return TimerGameEconomy::date - _news_type_data[ni.type].age * _settings_client.gui.news_message_timeout > ni.economy_date;
});
}
/**
@ -999,17 +971,17 @@ static void RemoveOldNewsItems()
*/
void ChangeVehicleNews(VehicleID from_index, VehicleID to_index)
{
for (NewsItem *ni = _oldest_news; ni != nullptr; ni = ni->next) {
if (ni->reftype1 == NR_VEHICLE && ni->ref1 == from_index) ni->ref1 = to_index;
if (ni->reftype2 == NR_VEHICLE && ni->ref2 == from_index) ni->ref2 = to_index;
if (ni->flags & NF_VEHICLE_PARAM0 && ni->params[0].data == from_index) ni->params[0] = to_index;
for (auto &ni : _news) {
if (ni.reftype1 == NR_VEHICLE && ni.ref1 == from_index) ni.ref1 = to_index;
if (ni.reftype2 == NR_VEHICLE && ni.ref2 == from_index) ni.ref2 = to_index;
if (ni.flags & NF_VEHICLE_PARAM0 && ni.params[0].data == from_index) ni.params[0] = to_index;
}
}
void NewsLoop()
{
/* no news item yet */
if (_total_news == 0) return;
if (std::empty(_news)) return;
static TimerGameEconomy::Month _last_clean_month = 0;
@ -1023,9 +995,9 @@ void NewsLoop()
}
/** Do a forced show of a specific message */
static void ShowNewsMessage(const NewsItem *ni)
static void ShowNewsMessage(NewsIterator ni)
{
assert(_total_news != 0);
assert(!std::empty(_news));
/* Delete the news window */
CloseWindowById(WC_NEWS_WINDOW, 0);
@ -1033,9 +1005,9 @@ static void ShowNewsMessage(const NewsItem *ni)
/* setup forced news item */
_forced_news = ni;
if (_forced_news != nullptr) {
if (_forced_news != std::end(_news)) {
CloseWindowById(WC_NEWS_WINDOW, 0);
ShowNewspaper(ni);
ShowNewspaper(&*ni);
}
}
@ -1054,26 +1026,26 @@ bool HideActiveNewsMessage()
/** Show previous news item */
void ShowLastNewsMessage()
{
const NewsItem *ni = nullptr;
if (_total_news == 0) {
return;
} else if (_forced_news == nullptr) {
if (std::empty(_news)) return;
NewsIterator ni;
if (_forced_news == std::end(_news)) {
/* Not forced any news yet, show the current one, unless a news window is
* open (which can only be the current one), then show the previous item */
if (_current_news == nullptr) {
if (_current_news == std::end(_news)) {
/* No news were shown yet resp. the last shown one was already deleted.
* Threat this as if _forced_news reached _oldest_news; so, wrap around and start anew with the latest. */
ni = _latest_news;
* Treat this as if _forced_news reached the oldest news; so, wrap around and start anew with the latest. */
ni = std::begin(_news);
} else {
const Window *w = FindWindowById(WC_NEWS_WINDOW, 0);
ni = (w == nullptr || (_current_news == _oldest_news)) ? _current_news : _current_news->prev;
ni = (w == nullptr || (std::next(_current_news) == std::end(_news))) ? _current_news : std::next(_current_news);
}
} else if (_forced_news == _oldest_news) {
} else if (std::next(_forced_news) == std::end(_news)) {
/* We have reached the oldest news, start anew with the latest */
ni = _latest_news;
ni = std::begin(_news);
} else {
/* 'Scrolling' through news history show each one in turn */
ni = _forced_news->prev;
ni = std::next(_forced_news);
}
bool wrap = false;
for (;;) {
@ -1082,11 +1054,11 @@ void ShowLastNewsMessage()
break;
}
ni = ni->prev;
if (ni == nullptr) {
++ni;
if (ni == std::end(_news)) {
if (wrap) break;
/* We have reached the oldest news, start anew with the latest */
ni = _latest_news;
ni = std::begin(_news);
wrap = true;
}
}
@ -1143,37 +1115,23 @@ struct MessageHistoryWindow : Window {
}
}
void OnPaint() override
{
this->OnInvalidateData(0);
this->DrawWidgets();
}
void DrawWidget(const Rect &r, WidgetID widget) const override
{
if (widget != WID_MH_BACKGROUND || _total_news == 0) return;
/* Find the first news item to display. */
NewsItem *ni = _latest_news;
for (int n = this->vscroll->GetPosition(); n > 0; n--) {
ni = ni->prev;
if (ni == nullptr) return;
}
if (widget != WID_MH_BACKGROUND || std::empty(_news)) return;
/* Fill the widget with news items. */
bool rtl = _current_text_dir == TD_RTL;
Rect news = r.Shrink(WidgetDimensions::scaled.framerect).Indent(this->date_width + WidgetDimensions::scaled.hsep_wide, rtl);
Rect date = r.Shrink(WidgetDimensions::scaled.framerect).WithWidth(this->date_width, rtl);
int y = news.top;
for (int n = this->vscroll->GetCapacity(); n > 0; n--) {
auto [first, last] = this->vscroll->GetVisibleRangeIterators(_news);
for (auto ni = first; ni != last; ++ni) {
SetDParam(0, ni->date);
DrawString(date.left, date.right, y, STR_JUST_DATE_TINY, TC_WHITE);
DrawNewsString(news.left, news.right, y, TC_WHITE, ni);
DrawNewsString(news.left, news.right, y, TC_WHITE, &*ni);
y += this->line_height;
ni = ni->prev;
if (ni == nullptr) return;
}
}
@ -1185,19 +1143,18 @@ struct MessageHistoryWindow : Window {
void OnInvalidateData([[maybe_unused]] int data = 0, [[maybe_unused]] bool gui_scope = true) override
{
if (!gui_scope) return;
this->vscroll->SetCount(_total_news);
this->vscroll->SetCount(std::size(_news));
}
void OnClick([[maybe_unused]] Point pt, WidgetID widget, [[maybe_unused]] int click_count) override
{
if (widget == WID_MH_BACKGROUND) {
NewsItem *ni = _latest_news;
if (ni == nullptr) return;
for (int n = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_MH_BACKGROUND, WidgetDimensions::scaled.framerect.top); n > 0; n--) {
ni = ni->prev;
if (ni == nullptr) return;
}
/* Scheduled window invalidations currently occur after the input loop, which means the scrollbar count
* could be invalid, so ensure it's correct now. Potentially this means that item clicked on might be
* different as well. */
this->vscroll->SetCount(std::size(_news));
auto ni = this->vscroll->GetScrolledItemFromWidget(_news, pt.y, this, widget);
if (ni == std::end(_news)) return;
ShowNewsMessage(ni);
}

View File

@ -16,6 +16,6 @@ void ShowLastNewsMessage();
void ShowMessageHistory();
bool HideActiveNewsMessage();
extern NewsItem *_latest_news;
const NewsContainer &GetNews();
#endif /* NEWS_GUI_H */

View File

@ -126,8 +126,6 @@ struct NewsAllocatedData {
/** Information about a single item of news. */
struct NewsItem {
NewsItem *prev; ///< Previous news item
NewsItem *next; ///< Next news item
StringID string_id; ///< Message text
TimerGameCalendar::Date date; ///< Calendar date to show for the news
TimerGameEconomy::Date economy_date; ///< Economy date of the news item, never shown but used to calculate age
@ -169,4 +167,7 @@ struct CompanyNewsInformation : NewsAllocatedData {
CompanyNewsInformation(const struct Company *c, const struct Company *other = nullptr);
};
using NewsContainer = std::list<NewsItem>; ///< Container type for storing news items.
using NewsIterator = NewsContainer::const_iterator; ///< Iterator type for news items.
#endif /* NEWS_TYPE_H */

View File

@ -145,9 +145,9 @@ struct StatusBarWindow : Window {
} else if (_pause_mode != PM_UNPAUSED) {
StringID msg = (_pause_mode & PM_PAUSED_LINK_GRAPH) ? STR_STATUSBAR_PAUSED_LINK_GRAPH : STR_STATUSBAR_PAUSED;
DrawString(tr, msg, TC_FROMSTRING, SA_HOR_CENTER);
} else if (this->ticker_scroll < TICKER_STOP && _statusbar_news_item != nullptr && _statusbar_news_item->string_id != 0) {
} else if (this->ticker_scroll < TICKER_STOP && GetStatusbarNews() != nullptr && GetStatusbarNews()->string_id != 0) {
/* Draw the scrolling news text */
if (!DrawScrollingStatusText(_statusbar_news_item, ScaleGUITrad(this->ticker_scroll), tr.left, tr.right, tr.top, tr.bottom)) {
if (!DrawScrollingStatusText(GetStatusbarNews(), ScaleGUITrad(this->ticker_scroll), tr.left, tr.right, tr.top, tr.bottom)) {
InvalidateWindowData(WC_STATUS_BAR, 0, SBI_NEWS_DELETED);
if (Company::IsValidID(_local_company)) {
/* This is the default text */