OpenTTD Source 20241222-master-gc72542431a
statusbar_gui.cpp
Go to the documentation of this file.
1/*
2 * This file is part of OpenTTD.
3 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
4 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
5 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
6 */
7
10#include "stdafx.h"
11#include "core/backup_type.hpp"
12#include "gfx_func.h"
13#include "news_func.h"
14#include "company_func.h"
15#include "string_func.h"
16#include "strings_func.h"
17#include "company_base.h"
18#include "tilehighlight_func.h"
19#include "news_gui.h"
20#include "company_gui.h"
21#include "window_gui.h"
22#include "saveload/saveload.h"
23#include "window_func.h"
24#include "statusbar_gui.h"
25#include "toolbar_gui.h"
27#include "zoom_func.h"
28#include "timer/timer.h"
30#include "timer/timer_window.h"
31
33
34#include "table/strings.h"
35#include "table/sprites.h"
36
37#include "safeguards.h"
38
39static bool DrawScrollingStatusText(const NewsItem *ni, int scroll_pos, int left, int right, int top, int bottom)
40{
42
43 /* Replace newlines and the likes with spaces. */
45
46 DrawPixelInfo tmp_dpi;
47 if (!FillDrawPixelInfo(&tmp_dpi, left, top, right - left, bottom)) return true;
48
49 int width = GetStringBoundingBox(message).width;
50 int pos = (_current_text_dir == TD_RTL) ? (scroll_pos - width) : (right - scroll_pos - left);
51
52 AutoRestoreBackup dpi_backup(_cur_dpi, &tmp_dpi);
53 DrawString(pos, INT16_MAX, 0, message, TC_LIGHT_BLUE, SA_LEFT | SA_FORCE);
54
55 return (_current_text_dir == TD_RTL) ? (pos < right - left) : (pos + width > 0);
56}
57
59 bool saving;
60 int ticker_scroll;
61
62 static const int TICKER_STOP = 1640;
63 static const int COUNTER_STEP = 2;
64 static constexpr auto REMINDER_START = std::chrono::milliseconds(1350);
65
66 StatusBarWindow(WindowDesc &desc) : Window(desc)
67 {
68 this->ticker_scroll = TICKER_STOP;
69
70 this->InitNested();
73 }
74
76 {
77 Point pt = { 0, _screen.height - sm_height };
78 return pt;
79 }
80
85
87 {
89 switch (widget) {
90 case WID_S_LEFT:
93 break;
94
95 case WID_S_RIGHT: {
96 int64_t max_money = UINT32_MAX;
97 for (const Company *c : Company::Iterate()) max_money = std::max<int64_t>(c->money, max_money);
98 SetDParam(0, 100LL * max_money);
100 break;
101 }
102
103 default:
104 return;
105 }
106
107 d.width += padding.width;
108 d.height += padding.height;
109 size = maxdim(d, size);
110 }
111
112 void DrawWidget(const Rect &r, WidgetID widget) const override
113 {
114 Rect tr = r.Shrink(WidgetDimensions::scaled.framerect, RectPadding::zero);
115 tr.top = CenterBounds(r.top, r.bottom, GetCharacterHeight(FS_NORMAL));
116 switch (widget) {
117 case WID_S_LEFT:
118 /* Draw the date */
121 break;
122
123 case WID_S_RIGHT: {
128 } else {
129 /* Draw company money, if any */
131 if (c != nullptr) {
132 SetDParam(0, c->money);
134 }
135 }
136 break;
137 }
138
139 case WID_S_MIDDLE:
140 /* Draw status bar */
141 if (this->saving) { // true when saving is active
143 } else if (_do_autosave) {
145 } else if (_pause_mode != PM_UNPAUSED) {
147 DrawString(tr, msg, TC_FROMSTRING, SA_HOR_CENTER);
148 } else if (this->ticker_scroll < TICKER_STOP && GetStatusbarNews() != nullptr && GetStatusbarNews()->string_id != 0) {
149 /* Draw the scrolling news text */
150 if (!DrawScrollingStatusText(GetStatusbarNews(), ScaleGUITrad(this->ticker_scroll), tr.left, tr.right, tr.top, tr.bottom)) {
153 /* This is the default text */
156 }
157 }
158 } else {
160 /* This is the default text */
163 }
164 }
165
166 if (!this->reminder_timeout.HasFired()) {
167 Dimension icon_size = GetSpriteSize(SPR_UNREAD_NEWS);
168 DrawSprite(SPR_UNREAD_NEWS, PAL_NONE, tr.right - icon_size.width, CenterBounds(r.top, r.bottom, icon_size.height));
169 }
170 break;
171 }
172 }
173
179 void OnInvalidateData([[maybe_unused]] int data = 0, [[maybe_unused]] bool gui_scope = true) override
180 {
181 if (!gui_scope) return;
182 switch (data) {
183 default: NOT_REACHED();
184 case SBI_SAVELOAD_START: this->saving = true; break;
185 case SBI_SAVELOAD_FINISH: this->saving = false; break;
186 case SBI_SHOW_TICKER: this->ticker_scroll = 0; break;
187 case SBI_SHOW_REMINDER: this->reminder_timeout.Reset(); break;
188 case SBI_NEWS_DELETED:
189 this->ticker_scroll = TICKER_STOP; // reset ticker ...
190 this->reminder_timeout.Abort(); // ... and reminder
191 break;
192 }
193 }
194
195 void OnClick([[maybe_unused]] Point pt, WidgetID widget, [[maybe_unused]] int click_count) override
196 {
197 switch (widget) {
198 case WID_S_MIDDLE: ShowLastNewsMessage(); break;
200 default: ResetObjectToPlace();
201 }
202 }
203
205 IntervalTimer<TimerWindow> ticker_scroll_interval = {std::chrono::milliseconds(15), [this](uint count) {
206 if (_pause_mode != PM_UNPAUSED) return;
207
208 if (this->ticker_scroll < TICKER_STOP) {
209 this->ticker_scroll += count;
211 }
212 }};
213
214 TimeoutTimer<TimerWindow> reminder_timeout = {REMINDER_START, [this]() {
216 }};
217
218 IntervalTimer<TimerGameCalendar> daily_interval = {{TimerGameCalendar::DAY, TimerGameCalendar::Priority::NONE}, [this](auto) {
220 }};
221};
222
223static constexpr NWidgetPart _nested_main_status_widgets[] = {
225 NWidget(WWT_PANEL, COLOUR_GREY, WID_S_LEFT), SetMinimalSize(140, 12), EndContainer(),
226 NWidget(WWT_PUSHBTN, COLOUR_GREY, WID_S_MIDDLE), SetMinimalSize(40, 12), SetDataTip(0x0, STR_STATUSBAR_TOOLTIP_SHOW_LAST_NEWS), SetResize(1, 0),
227 NWidget(WWT_PUSHBTN, COLOUR_GREY, WID_S_RIGHT), SetMinimalSize(140, 12),
228 EndContainer(),
229};
230
231static WindowDesc _main_status_desc(
232 WDP_MANUAL, nullptr, 0, 0,
235 _nested_main_status_widgets
236);
237
242{
243 const StatusBarWindow *w = dynamic_cast<StatusBarWindow*>(FindWindowById(WC_STATUS_BAR, 0));
244 return w != nullptr && w->ticker_scroll < StatusBarWindow::TICKER_STOP;
245}
246
251{
252 new StatusBarWindow(_main_status_desc);
253}
Class for backupping variables and making sure they are restored later.
#define CLRBITS(x, y)
Clears several bits in a variable.
An interval timer will fire every interval, and will continue to fire until it is deleted.
Definition timer.h:76
A timeout timer will fire once after the interval.
Definition timer.h:116
void Reset()
Reset the timer, so it will fire again after the timeout.
Definition timer.h:140
bool HasFired() const
Check whether the timeout occurred.
Definition timer.h:171
void Abort()
Abort the timer so it doesn't fire if it hasn't yet.
Definition timer.h:161
static Date date
Current date in days (day counter).
static constexpr TimerGame< struct Calendar >::Year MAX_YEAR
MAX_YEAR, nicely rounded value of the number of years that can be encoded in a single 32 bits date,...
static constexpr Date DateAtStartOfYear(Year year)
Calculate the date of the first day of a given year.
static WidgetDimensions scaled
Widget dimensions scaled for current zoom level.
Definition window_gui.h:28
Definition of stuff that is very close to a company, like the company struct itself.
CompanyID _local_company
Company controlled by the human player at this client. Can also be COMPANY_SPECTATOR.
Functions related to companies.
void ShowCompanyFinances(CompanyID company)
Open the finances window of a company.
GUI Functions related to companies.
@ COMPANY_SPECTATOR
The client is spectating.
int GetCharacterHeight(FontSize size)
Get height of a character for a given font size.
Definition fontcache.cpp:77
Dimension maxdim(const Dimension &d1, const Dimension &d2)
Compute bounding box of both dimensions.
Geometry functions.
Dimension GetSpriteSize(SpriteID sprid, Point *offset, ZoomLevel zoom)
Get the size of a sprite.
Definition gfx.cpp:922
PauseMode _pause_mode
The current pause mode.
Definition gfx.cpp:50
Dimension GetStringBoundingBox(std::string_view str, FontSize start_fontsize)
Return the string dimension in pixels.
Definition gfx.cpp:851
int DrawString(int left, int right, int top, std::string_view str, TextColour colour, StringAlignment align, bool underline, FontSize fontsize)
Draw string, possibly truncated to make it fit in its allocated space.
Definition gfx.cpp:657
void DrawSprite(SpriteID img, PaletteID pal, int x, int y, const SubSprite *sub, ZoomLevel zoom)
Draw a sprite, not in a viewport.
Definition gfx.cpp:988
bool FillDrawPixelInfo(DrawPixelInfo *n, int left, int top, int width, int height)
Set up a clipping area for only drawing into a certain area.
Definition gfx.cpp:1548
Functions related to the gfx engine.
int CenterBounds(int min, int max, int size)
Determine where to draw a centred object inside a widget.
Definition gfx_func.h:166
@ SA_LEFT
Left align the text.
Definition gfx_type.h:343
@ SA_HOR_CENTER
Horizontally center the text.
Definition gfx_type.h:344
@ SA_FORCE
Force the alignment, i.e. don't swap for RTL languages.
Definition gfx_type.h:355
@ SA_VERT_CENTER
Vertically center the text.
Definition gfx_type.h:349
@ FS_NORMAL
Index of the normal font in the font tables.
Definition gfx_type.h:209
constexpr NWidgetPart SetDataTip(uint32_t data, StringID tip)
Widget part function for setting the data and tooltip.
constexpr NWidgetPart SetMinimalSize(int16_t x, int16_t y)
Widget part function for setting the minimal size.
constexpr NWidgetPart NWidget(WidgetType tp, Colours col, WidgetID idx=-1)
Widget part function for starting a new 'real' widget.
constexpr NWidgetPart EndContainer()
Widget part function for denoting the end of a container (horizontal, vertical, WWT_FRAME,...
constexpr NWidgetPart SetResize(int16_t dx, int16_t dy)
Widget part function for setting the resize step.
Functions related to news.
const NewsItem * GetStatusbarNews()
Get pointer to the current status bar news item.
Definition news_gui.cpp:70
void ShowLastNewsMessage()
Show previous news item.
GUI functions related to the news.
@ PM_UNPAUSED
A normal unpaused game.
Definition openttd.h:69
@ PM_PAUSED_LINK_GRAPH
A game paused due to the link graph schedule lagging.
Definition openttd.h:76
A number of safeguards to prevent using unsafe methods.
bool _do_autosave
are we doing an autosave at the moment?
Definition saveload.cpp:66
Functions/types related to saving and loading games.
GameSettings _settings_game
Game settings of a running game or the scenario editor.
Definition settings.cpp:57
This file contains all sprite-related enums and defines.
void ShowStatusBar()
Show our status bar.
bool IsNewsTickerShown()
Checks whether the news ticker is currently being used.
Functions, definitions and such used only by the GUI.
@ SBI_SHOW_REMINDER
show a reminder (dot on the right side of the statusbar)
@ SBI_SAVELOAD_FINISH
finished saving
@ SBI_SHOW_TICKER
start scrolling news
@ SBI_SAVELOAD_START
started saving
@ SBI_NEWS_DELETED
abort current news display (active news were deleted)
Types related to the statusbar widgets.
@ WID_S_LEFT
Left part of the statusbar; date is shown there.
@ WID_S_MIDDLE
Middle part; current news or company name or *** SAVING *** or *** PAUSED ***.
@ WID_S_RIGHT
Right part; bank balance.
Definition of base types and functions in a cross-platform compatible way.
static void StrMakeValid(T &dst, const char *str, const char *last, StringValidationSettings settings)
Copies the valid (UTF-8) characters from str up to last to the dst.
Definition string.cpp:107
Functions related to low-level strings.
@ SVS_REPLACE_TAB_CR_NL_WITH_SPACE
Replace tabs ('\t'), carriage returns ('\r') and newlines (' ') with spaces.
Definition string_type.h:54
void SetDParamMaxValue(size_t n, uint64_t max_value, uint min_count, FontSize size)
Set DParam n to some number that is suitable for string size computations.
Definition strings.cpp:127
void SetDParam(size_t n, uint64_t v)
Set a string parameter v at index n in the global string parameter array.
Definition strings.cpp:104
std::string GetString(StringID string)
Resolve the given StringID into a std::string with all the associated DParam lookups and formatting.
Definition strings.cpp:333
void CopyInDParam(const std::span< const StringParameterData > backup)
Copy the parameters from the backup into the global string parameter array.
Definition strings.cpp:159
TextDirection _current_text_dir
Text direction of the currently selected language.
Definition strings.cpp:56
Functions related to OTTD's strings.
@ TD_RTL
Text is written right-to-left by default.
uint32_t StringID
Numeric value that represents a string, independent of the selected language.
Class to backup a specific variable and restore it upon destruction of this object to prevent stack v...
Money money
Money owned by the company.
bool infinite_money
whether spending money despite negative balance is allowed
Dimensions (a width and height) of a rectangle in 2D.
Data about how and where to blit pixels.
Definition gfx_type.h:157
DifficultySettings difficulty
settings related to the difficulty
Partial widget specification to allow NWidgets to be written nested.
Information about a single item of news.
Definition news_type.h:128
std::vector< StringParameterData > params
Parameters for string resolving.
Definition news_type.h:142
StringID string_id
Message text.
Definition news_type.h:129
Coordinates of a point in 2D.
static bool IsValidID(size_t index)
Tests whether given index can be used to get valid (non-nullptr) Titem.
static Pool::IterateWrapper< Titem > Iterate(size_t from=0)
Returns an iterable ensemble of all valid Titem.
static Titem * GetIfValid(size_t index)
Returns Titem with given index.
Specification of a rectangle with absolute coordinates of all edges.
Rect Shrink(int s) const
Copy and shrink Rect by s pixels.
void DrawWidget(const Rect &r, WidgetID widget) const override
Draw the contents of a nested widget.
void FindWindowPlacementAndResize(int def_width, int def_height) override
Resize window towards the default size.
void OnClick(Point pt, WidgetID widget, int click_count) override
A click with the left mouse button has been made on the window.
void UpdateWidgetSize(WidgetID widget, Dimension &size, const Dimension &padding, Dimension &fill, Dimension &resize) override
Update size and resize step of a widget in the window.
IntervalTimer< TimerWindow > ticker_scroll_interval
Move information on the ticker slowly from one side to the other.
static const int TICKER_STOP
scrolling is finished when counter reaches this value
Point OnInitialPosition(int16_t sm_width, int16_t sm_height, int window_number) override
Compute the initial position of the window.
void OnInvalidateData(int data=0, bool gui_scope=true) override
Some data on this window has become invalid.
static const int COUNTER_STEP
this is subtracted from active counters every tick
static constexpr auto REMINDER_START
time in ms for reminder notification (red dot on the right) to stay
High level window description.
Definition window_gui.h:159
Data structure for an opened window.
Definition window_gui.h:273
void SetWidgetDirty(WidgetID widget_index) const
Invalidate a widget, i.e.
Definition window.cpp:551
ResizeInfo resize
Resize information.
Definition window_gui.h:314
const NWID * GetWidget(WidgetID widnum) const
Get the nested widget with number widnum from the nested widget tree.
Definition window_gui.h:977
void InitNested(WindowNumber number=0)
Perform complete initialization of the Window with nested widgets, to allow use.
Definition window.cpp:1746
WindowFlags flags
Window flags.
Definition window_gui.h:300
virtual void FindWindowPlacementAndResize(int def_width, int def_height)
Resize window towards the default size.
Definition window.cpp:1420
WindowNumber window_number
Window number within the window class.
Definition window_gui.h:302
Functions related to tile highlights.
void ResetObjectToPlace()
Reset the cursor and mouse mode handling back to default (normal cursor, only clicking in windows).
Definition of Interval and OneShot timers.
Definition of the game-calendar-timer.
Definition of the Window system.
uint _toolbar_width
Width of the toolbar, shared by statusbar.
Stuff related to the (main) toolbar.
static RectPadding ScaleGUITrad(const RectPadding &r)
Scale a RectPadding to GUI zoom level.
Definition widget.cpp:35
@ WWT_PUSHBTN
Normal push-button (no toggle button) with custom drawing.
@ NWID_HORIZONTAL
Horizontal container.
Definition widget_type.h:75
@ WWT_PANEL
Simple depressed panel.
Definition widget_type.h:50
int PositionStatusbar(Window *w)
(Re)position statusbar window at the screen.
Definition window.cpp:3401
void InvalidateWindowData(WindowClass cls, WindowNumber number, int data, bool gui_scope)
Mark window data of the window of a given class and specific window number as invalid (in need of re-...
Definition window.cpp:3219
Window * FindWindowById(WindowClass cls, WindowNumber number)
Find a window by its class and window number.
Definition window.cpp:1098
Window functions not directly related to making/drawing windows.
Functions, definitions and such used only by the GUI.
@ WF_WHITE_BORDER
Window white border counter bit mask.
Definition window_gui.h:236
@ WDF_NO_CLOSE
This window can't be interactively closed.
Definition window_gui.h:206
@ WDF_NO_FOCUS
This window won't get focus/make any other window lose focus when click.
Definition window_gui.h:205
@ WDP_MANUAL
Manually align the window (so no automatic location finding)
Definition window_gui.h:146
int WidgetID
Widget ID.
Definition window_type.h:18
@ WC_STATUS_BAR
Statusbar (at the bottom of your screen); Window numbers:
Definition window_type.h:64
@ WC_NONE
No window, redirects to WC_MAIN_WINDOW.
Definition window_type.h:45
Functions related to zooming.