OpenTTD
statusbar_gui.cpp
Go to the documentation of this file.
1 /* $Id: statusbar_gui.cpp 27146 2015-02-13 21:13:45Z frosch $ */
2 
3 /*
4  * This file is part of OpenTTD.
5  * 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.
6  * 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.
7  * 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/>.
8  */
9 
12 #include "stdafx.h"
13 #include "date_func.h"
14 #include "gfx_func.h"
15 #include "news_func.h"
16 #include "company_func.h"
17 #include "string_func.h"
18 #include "strings_func.h"
19 #include "company_base.h"
20 #include "tilehighlight_func.h"
21 #include "news_gui.h"
22 #include "company_gui.h"
23 #include "window_gui.h"
24 #include "saveload/saveload.h"
25 #include "window_func.h"
26 #include "statusbar_gui.h"
27 #include "toolbar_gui.h"
28 #include "core/geometry_func.hpp"
29 
31 
32 #include "table/strings.h"
33 #include "table/sprites.h"
34 
35 #include "safeguards.h"
36 
37 static bool DrawScrollingStatusText(const NewsItem *ni, int scroll_pos, int left, int right, int top, int bottom)
38 {
39  CopyInDParam(0, ni->params, lengthof(ni->params));
40  StringID str = ni->string_id;
41 
42  char buf[512];
43  GetString(buf, str, lastof(buf));
44  const char *s = buf;
45 
46  char buffer[256];
47  char *d = buffer;
48  const char *last = lastof(buffer);
49 
50  for (;;) {
51  WChar c = Utf8Consume(&s);
52  if (c == 0) {
53  break;
54  } else if (c == '\n') {
55  if (d + 4 >= last) break;
56  d[0] = d[1] = d[2] = d[3] = ' ';
57  d += 4;
58  } else if (IsPrintable(c)) {
59  if (d + Utf8CharLen(c) >= last) break;
60  d += Utf8Encode(d, c);
61  }
62  }
63  *d = '\0';
64 
65  DrawPixelInfo tmp_dpi;
66  if (!FillDrawPixelInfo(&tmp_dpi, left, top, right - left, bottom)) return true;
67 
68  int width = GetStringBoundingBox(buffer).width;
69  int pos = (_current_text_dir == TD_RTL) ? (scroll_pos - width) : (right - scroll_pos - left);
70 
71  DrawPixelInfo *old_dpi = _cur_dpi;
72  _cur_dpi = &tmp_dpi;
73  DrawString(pos, INT16_MAX, 0, buffer, TC_LIGHT_BLUE, SA_LEFT | SA_FORCE);
74  _cur_dpi = old_dpi;
75 
76  return (_current_text_dir == TD_RTL) ? (pos < right - left) : (pos + width > 0);
77 }
78 
80  bool saving;
81  int ticker_scroll;
82  int reminder_timeout;
83 
84  static const int TICKER_STOP = 1640;
85  static const int REMINDER_START = 91;
86  static const int REMINDER_STOP = 0;
87  static const int COUNTER_STEP = 2;
88 
89  StatusBarWindow(WindowDesc *desc) : Window(desc)
90  {
91  this->ticker_scroll = TICKER_STOP;
92  this->reminder_timeout = REMINDER_STOP;
93 
94  this->InitNested();
96  PositionStatusbar(this);
97  }
98 
99  virtual Point OnInitialPosition(int16 sm_width, int16 sm_height, int window_number)
100  {
101  Point pt = { 0, _screen.height - sm_height };
102  return pt;
103  }
104 
105  virtual void FindWindowPlacementAndResize(int def_width, int def_height)
106  {
108  }
109 
110  virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
111  {
112  Dimension d;
113  switch (widget) {
114  case WID_S_LEFT:
116  d = GetStringBoundingBox(STR_WHITE_DATE_LONG);
117  break;
118 
119  case WID_S_RIGHT: {
120  int64 max_money = UINT32_MAX;
121  const Company *c;
122  FOR_ALL_COMPANIES(c) max_money = max<int64>(c->money, max_money);
123  SetDParam(0, 100LL * max_money);
124  d = GetStringBoundingBox(STR_COMPANY_MONEY);
125  break;
126  }
127 
128  default:
129  return;
130  }
131 
132  d.width += padding.width;
133  d.height += padding.height;
134  *size = maxdim(d, *size);
135  }
136 
137  virtual void DrawWidget(const Rect &r, int widget) const
138  {
139  switch (widget) {
140  case WID_S_LEFT:
141  /* Draw the date */
142  SetDParam(0, _date);
143  DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, STR_WHITE_DATE_LONG, TC_FROMSTRING, SA_HOR_CENTER);
144  break;
145 
146  case WID_S_RIGHT: {
147  /* Draw company money, if any */
149  if (c != NULL) {
150  SetDParam(0, c->money);
151  DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, STR_COMPANY_MONEY, TC_FROMSTRING, SA_HOR_CENTER);
152  }
153  break;
154  }
155 
156  case WID_S_MIDDLE:
157  /* Draw status bar */
158  if (this->saving) { // true when saving is active
159  DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, STR_STATUSBAR_SAVING_GAME, TC_FROMSTRING, SA_HOR_CENTER);
160  } else if (_do_autosave) {
161  DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, STR_STATUSBAR_AUTOSAVE, TC_FROMSTRING, SA_HOR_CENTER);
162  } else if (_pause_mode != PM_UNPAUSED) {
163  DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, STR_STATUSBAR_PAUSED, TC_FROMSTRING, SA_HOR_CENTER);
164  } else if (this->ticker_scroll < TICKER_STOP && FindWindowById(WC_NEWS_WINDOW, 0) == NULL && _statusbar_news_item != NULL && _statusbar_news_item->string_id != 0) {
165  /* Draw the scrolling news text */
166  if (!DrawScrollingStatusText(_statusbar_news_item, this->ticker_scroll, r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, r.bottom)) {
169  /* This is the default text */
171  DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, STR_STATUSBAR_COMPANY_NAME, TC_FROMSTRING, SA_HOR_CENTER);
172  }
173  }
174  } else {
176  /* This is the default text */
178  DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, STR_STATUSBAR_COMPANY_NAME, TC_FROMSTRING, SA_HOR_CENTER);
179  }
180  }
181 
182  if (this->reminder_timeout > 0) {
183  Dimension icon_size = GetSpriteSize(SPR_UNREAD_NEWS);
184  DrawSprite(SPR_UNREAD_NEWS, PAL_NONE, r.right - WD_FRAMERECT_RIGHT - icon_size.width, r.top + WD_FRAMERECT_TOP + (int)(FONT_HEIGHT_NORMAL - icon_size.height) / 2);
185  }
186  break;
187  }
188  }
189 
195  virtual void OnInvalidateData(int data = 0, bool gui_scope = true)
196  {
197  if (!gui_scope) return;
198  switch (data) {
199  default: NOT_REACHED();
200  case SBI_SAVELOAD_START: this->saving = true; break;
201  case SBI_SAVELOAD_FINISH: this->saving = false; break;
202  case SBI_SHOW_TICKER: this->ticker_scroll = 0; break;
203  case SBI_SHOW_REMINDER: this->reminder_timeout = REMINDER_START; break;
204  case SBI_NEWS_DELETED:
205  this->ticker_scroll = TICKER_STOP; // reset ticker ...
206  this->reminder_timeout = REMINDER_STOP; // ... and reminder
207  break;
208  }
209  }
210 
211  virtual void OnClick(Point pt, int widget, int click_count)
212  {
213  switch (widget) {
214  case WID_S_MIDDLE: ShowLastNewsMessage(); break;
216  default: ResetObjectToPlace();
217  }
218  }
219 
220  virtual void OnTick()
221  {
222  if (_pause_mode != PM_UNPAUSED) return;
223 
224  if (this->ticker_scroll < TICKER_STOP) { // Scrolling text
225  this->ticker_scroll += COUNTER_STEP;
227  }
228 
229  if (this->reminder_timeout > REMINDER_STOP) { // Red blot to show there are new unread newsmessages
230  this->reminder_timeout -= COUNTER_STEP;
231  } else if (this->reminder_timeout < REMINDER_STOP) {
232  this->reminder_timeout = REMINDER_STOP;
234  }
235  }
236 };
237 
238 static const NWidgetPart _nested_main_status_widgets[] = {
240  NWidget(WWT_PANEL, COLOUR_GREY, WID_S_LEFT), SetMinimalSize(140, 12), EndContainer(),
241  NWidget(WWT_PUSHBTN, COLOUR_GREY, WID_S_MIDDLE), SetMinimalSize(40, 12), SetDataTip(0x0, STR_STATUSBAR_TOOLTIP_SHOW_LAST_NEWS), SetResize(1, 0),
242  NWidget(WWT_PUSHBTN, COLOUR_GREY, WID_S_RIGHT), SetMinimalSize(140, 12),
243  EndContainer(),
244 };
245 
246 static WindowDesc _main_status_desc(
247  WDP_MANUAL, NULL, 0, 0,
249  WDF_NO_FOCUS,
250  _nested_main_status_widgets, lengthof(_nested_main_status_widgets)
251 );
252 
257 {
258  const StatusBarWindow *w = dynamic_cast<StatusBarWindow*>(FindWindowById(WC_STATUS_BAR, 0));
259  return w != NULL && w->ticker_scroll < StatusBarWindow::TICKER_STOP;
260 }
261 
266 {
267  new StatusBarWindow(&_main_status_desc);
268 }
Functions related to OTTD&#39;s strings.
virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
Update size and resize step of a widget in the window.
start scrolling news
Definition: statusbar_gui.h:19
Definition of stuff that is very close to a company, like the company struct itself.
static Titem * GetIfValid(size_t index)
Returns Titem with given index.
Definition: pool_type.hpp:257
static const int DAYS_IN_YEAR
days per year
Definition: date_type.h:31
Data about how and where to blit pixels.
Definition: gfx_type.h:156
Horizontally center the text.
Definition: gfx_func.h:99
ResizeInfo resize
Resize information.
Definition: window_gui.h:317
static NWidgetPart SetResize(int16 dx, int16 dy)
Widget part function for setting the resize step.
Definition: widget_type.h:930
A normal unpaused game.
Definition: openttd.h:58
static const int REMINDER_START
initial value of the reminder counter (right dot on the right)
High level window description.
Definition: window_gui.h:168
Middle part; current news or company name or *** SAVING *** or *** PAUSED ***.
WindowFlags flags
Window flags.
Definition: window_gui.h:305
Functions related to dates.
void SetWidgetDirty(byte widget_index) const
Invalidate a widget, i.e.
Definition: window.cpp:577
Offset at top to draw the frame rectangular area.
Definition: window_gui.h:64
Types related to the statusbar widgets.
Horizontal container.
Definition: widget_type.h:75
Window * FindWindowById(WindowClass cls, WindowNumber number)
Find a window by its class and window number.
Definition: window.cpp:1105
Left part of the statusbar; date is shown there.
void CopyInDParam(int offs, const uint64 *src, int num)
Copy num string parameters from array src into the global string parameter array. ...
Definition: strings.cpp:138
Normal push-button (no toggle button) with custom drawing.
Definition: widget_type.h:103
uint64 params[10]
Parameters for string resolving.
Definition: news_type.h:154
#define lastof(x)
Get the last element of an fixed size array.
Definition: depend.cpp:50
The client is spectating.
Definition: company_type.h:37
virtual void OnInvalidateData(int data=0, bool gui_scope=true)
Some data on this window has become invalid.
#define CLRBITS(x, y)
Clears several bits in a variable.
Right part; bank balance.
virtual void OnClick(Point pt, int widget, int click_count)
A click with the left mouse button has been made on the window.
virtual void OnTick()
Called once per (game) tick.
Functions, definitions and such used only by the GUI.
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:1480
CompanyByte _local_company
Company controlled by the human player at this client. Can also be COMPANY_SPECTATOR.
Definition: company_cmd.cpp:46
Force the alignment, i.e. don&#39;t swap for RTL languages.
Definition: gfx_func.h:110
Partial widget specification to allow NWidgets to be written nested.
Definition: widget_type.h:910
Data structure for an opened window.
Definition: window_gui.h:271
void InitNested(WindowNumber number=0)
Perform complete initialization of the Window with nested widgets, to allow use.
Definition: window.cpp:1833
int PositionStatusbar(Window *w)
(Re)position statusbar window at the screen.
Definition: window.cpp:3407
virtual void FindWindowPlacementAndResize(int def_width, int def_height)
Resize window towards the default size.
Functions related to low-level strings.
Functions/types related to saving and loading games.
StringID string_id
Message text.
Definition: news_type.h:137
GUI functions related to the news.
#define FONT_HEIGHT_NORMAL
Height of characters in the normal (FS_NORMAL) font.
Definition: gfx_func.h:180
static NWidgetPart SetDataTip(uint32 data, StringID tip)
Widget part function for setting the data and tooltip.
Definition: widget_type.h:1014
Functions related to the gfx engine.
abort current news display (active news were deleted)
Definition: statusbar_gui.h:21
static const int COUNTER_STEP
this is subtracted from active counters every tick
static NWidgetPart SetMinimalSize(int16 x, int16 y)
Widget part function for setting the minimal size.
Definition: widget_type.h:947
Definition of base types and functions in a cross-platform compatible way.
A number of safeguards to prevent using unsafe methods.
Geometry functions.
Simple depressed panel.
Definition: widget_type.h:50
show a reminder (dot on the right side of the statusbar)
Definition: statusbar_gui.h:20
GUI Functions related to companies.
static int8 Utf8CharLen(WChar c)
Return the length of a UTF-8 encoded character.
Definition: string_func.h:99
void ShowLastNewsMessage()
Show previous news item.
Definition: news_gui.cpp:916
static NWidgetPart NWidget(WidgetType tp, Colours col, int16 idx=-1)
Widget part function for starting a new &#39;real&#39; widget.
Definition: widget_type.h:1114
Money money
Money owned by the company.
Definition: company_base.h:64
int DrawString(int left, int right, int top, const char *str, TextColour colour, StringAlignment align, bool underline, FontSize fontsize)
Draw string, possibly truncated to make it fit in its allocated space.
Definition: gfx.cpp:499
#define lengthof(x)
Return the length of an fixed size array.
Definition: depend.cpp:42
PauseModeByte _pause_mode
The current pause mode.
Definition: gfx.cpp:48
uint32 StringID
Numeric value that represents a string, independent of the selected language.
Definition: strings_type.h:18
Dimension GetStringBoundingBox(const char *str, FontSize start_fontsize)
Return the string dimension in pixels.
Definition: gfx.cpp:699
virtual void DrawWidget(const Rect &r, int widget) const
Draw the contents of a nested widget.
Dimension maxdim(const Dimension &d1, const Dimension &d2)
Compute bounding box of both dimensions.
No window, redirects to WC_MAIN_WINDOW.
Definition: window_type.h:40
Functions related to companies.
uint _toolbar_width
Width of the toolbar, shared by statusbar.
Definition: toolbar_gui.cpp:61
TextDirection _current_text_dir
Text direction of the currently selected language.
Definition: strings.cpp:52
This window won&#39;t get focus/make any other window lose focus when click.
Definition: window_gui.h:212
void SetDParamMaxValue(uint n, uint64 max_value, uint min_count, FontSize size)
Set DParam n to some number that is suitable for string size computations.
Definition: strings.cpp:105
static NWidgetPart EndContainer()
Widget part function for denoting the end of a container (horizontal, vertical, WWT_FRAME, WWT_INSET, or WWT_PANEL).
Definition: widget_type.h:999
Statusbar (at the bottom of your screen); Window numbers:
Definition: window_type.h:59
Coordinates of a point in 2D.
Dimension GetSpriteSize(SpriteID sprid, Point *offset, ZoomLevel zoom)
Get the size of a sprite.
Definition: gfx.cpp:768
void ShowCompanyFinances(CompanyID company)
Open the finances window of a company.
static bool IsValidID(size_t index)
Tests whether given index can be used to get valid (non-NULL) Titem.
Definition: pool_type.hpp:235
bool IsNewsTickerShown()
Checks whether the news ticker is currently being used.
static const int REMINDER_STOP
reminder disappears when counter reaches this value
size_t Utf8Encode(char *buf, WChar c)
Encode a unicode character and place it in the buffer.
Definition: string.cpp:477
virtual void FindWindowPlacementAndResize(int def_width, int def_height)
Resize window towards the default size.
Definition: window.cpp:1498
Offset at right to draw the frame rectangular area.
Definition: window_gui.h:63
void ShowStatusBar()
Show our status bar.
void ResetObjectToPlace()
Reset the cursor and mouse mode handling back to default (normal cursor, only clicking in windows)...
Definition: viewport.cpp:3211
Specification of a rectangle with absolute coordinates of all edges.
Text is written right-to-left by default.
Definition: strings_type.h:26
WindowNumber window_number
Window number within the window class.
Definition: window_gui.h:307
Left align the text.
Definition: gfx_func.h:98
Functions related to tile highlights.
Window functions not directly related to making/drawing windows.
finished saving
Definition: statusbar_gui.h:18
Manually align the window (so no automatic location finding)
Definition: window_gui.h:155
Functions related to news.
Functions, definitions and such used only by the GUI.
virtual Point OnInitialPosition(int16 sm_width, int16 sm_height, int window_number)
Compute the initial position of the window.
Date _date
Current date in days (day counter)
Definition: date.cpp:28
uint32 WChar
Type for wide characters, i.e.
Definition: string_type.h:35
started saving
Definition: statusbar_gui.h:17
Window white border counter bit mask.
Definition: window_gui.h:242
Dimensions (a width and height) of a rectangle in 2D.
Offset at left to draw the frame rectangular area.
Definition: window_gui.h:62
static const Year MAX_YEAR
MAX_YEAR, nicely rounded value of the number of years that can be encoded in a single 32 bits date...
Definition: date_type.h:94
bool _do_autosave
are we doing an autosave at the moment?
Definition: saveload.cpp:278
This file contains all sprite-related enums and defines.
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:833
Information about a single item of news.
Definition: news_type.h:134
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:3220
News window; Window numbers:
Definition: window_type.h:243
static const int TICKER_STOP
scrolling is finished when counter reaches this value
Stuff related to the (main) toolbar.
static void SetDParam(uint n, uint64 v)
Set a string parameter v at index n in the global string parameter array.
Definition: strings_func.h:201