OpenTTD
story_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 "window_gui.h"
12 #include "strings_func.h"
13 #include "date_func.h"
14 #include "gui.h"
15 #include "story_base.h"
16 #include "core/geometry_func.hpp"
17 #include "company_func.h"
18 #include "command_func.h"
19 #include "widgets/dropdown_type.h"
20 #include "widgets/dropdown_func.h"
21 #include "sortlist_type.h"
22 #include "goal_base.h"
23 #include "viewport_func.h"
24 #include "window_func.h"
25 #include "company_base.h"
26 
27 #include "widgets/story_widget.h"
28 
29 #include "table/strings.h"
30 #include "table/sprites.h"
31 
32 #include "safeguards.h"
33 
36 
38 protected:
40 
45 
46  static GUIStoryPageList::SortFunction * const page_sorter_funcs[];
47  static GUIStoryPageElementList::SortFunction * const page_element_sorter_funcs[];
48 
51  {
52  if (this->story_pages.NeedRebuild()) {
53  this->story_pages.clear();
54 
55  for (const StoryPage *p : StoryPage::Iterate()) {
56  if (this->IsPageAvailable(p)) {
57  this->story_pages.push_back(p);
58  }
59  }
60 
61  this->story_pages.shrink_to_fit();
62  this->story_pages.RebuildDone();
63  }
64 
65  this->story_pages.Sort();
66  }
67 
69  static bool PageOrderSorter(const StoryPage * const &a, const StoryPage * const &b)
70  {
71  return a->sort_value < b->sort_value;
72  }
73 
76  {
77  if (this->story_page_elements.NeedRebuild()) {
78  this->story_page_elements.clear();
79 
80  const StoryPage *p = GetSelPage();
81  if (p != nullptr) {
82  for (const StoryPageElement *pe : StoryPageElement::Iterate()) {
83  if (pe->page == p->index) {
84  this->story_page_elements.push_back(pe);
85  }
86  }
87  }
88 
89  this->story_page_elements.shrink_to_fit();
90  this->story_page_elements.RebuildDone();
91  }
92 
93  this->story_page_elements.Sort();
94  }
95 
97  static bool PageElementOrderSorter(const StoryPageElement * const &a, const StoryPageElement * const &b)
98  {
99  return a->sort_value < b->sort_value;
100  }
101 
102  /*
103  * Checks if a given page should be visible in the story book.
104  * @param page The page to check.
105  * @return True if the page should be visible, otherwise false.
106  */
107  bool IsPageAvailable(const StoryPage *page) const
108  {
109  return page->company == INVALID_COMPANY || page->company == this->window_number;
110  }
111 
117  {
118  if (!_story_page_pool.IsValidID(selected_page_id)) return nullptr;
119  return _story_page_pool.Get(selected_page_id);
120  }
121 
126  int GetSelPageNum() const
127  {
128  int page_number = 0;
129  for (const StoryPage *p : this->story_pages) {
130  if (p->index == this->selected_page_id) {
131  return page_number;
132  }
133  page_number++;
134  }
135  return -1;
136  }
137 
142  {
143  /* Verify that the selected page exist. */
144  if (!_story_page_pool.IsValidID(this->selected_page_id)) return false;
145 
146  return this->story_pages.front()->index == this->selected_page_id;
147  }
148 
153  {
154  /* Verify that the selected page exist. */
155  if (!_story_page_pool.IsValidID(this->selected_page_id)) return false;
156 
157  if (this->story_pages.size() <= 1) return true;
158  const StoryPage *last = this->story_pages.back();
159  return last->index == this->selected_page_id;
160  }
161 
166  {
167  /* Generate generic title if selected page have no custom title. */
168  StoryPage *page = this->GetSelPage();
169  if (page != nullptr && page->title == nullptr) {
170  SetDParam(0, GetSelPageNum() + 1);
171  GetString(selected_generic_title, STR_STORY_BOOK_GENERIC_PAGE_ITEM, lastof(selected_generic_title));
172  }
173 
174  this->story_page_elements.ForceRebuild();
176 
177  this->vscroll->SetCount(this->GetContentHeight());
181  }
182 
187  {
188  if (!_story_page_pool.IsValidID(this->selected_page_id)) return;
189 
190  /* Find the last available page which is previous to the current selected page. */
191  const StoryPage *last_available;
192  last_available = nullptr;
193  for (const StoryPage *p : this->story_pages) {
194  if (p->index == this->selected_page_id) {
195  if (last_available == nullptr) return; // No previous page available.
196  this->SetSelectedPage(last_available->index);
197  return;
198  }
199  last_available = p;
200  }
201  }
202 
207  {
208  if (!_story_page_pool.IsValidID(this->selected_page_id)) return;
209 
210  /* Find selected page. */
211  for (auto iter = this->story_pages.begin(); iter != this->story_pages.end(); iter++) {
212  const StoryPage *p = *iter;
213  if (p->index == this->selected_page_id) {
214  /* Select the page after selected page. */
215  iter++;
216  if (iter != this->story_pages.end()) {
217  this->SetSelectedPage((*iter)->index);
218  }
219  return;
220  }
221  }
222  }
223 
228  {
229  DropDownList list;
230  uint16 page_num = 1;
231  for (const StoryPage *p : this->story_pages) {
232  bool current_page = p->index == this->selected_page_id;
233  DropDownListStringItem *item = nullptr;
234  if (p->title != nullptr) {
235  item = new DropDownListCharStringItem(p->title, p->index, current_page);
236  } else {
237  /* No custom title => use a generic page title with page number. */
238  DropDownListParamStringItem *str_item =
239  new DropDownListParamStringItem(STR_STORY_BOOK_GENERIC_PAGE_ITEM, p->index, current_page);
240  str_item->SetParam(0, page_num);
241  item = str_item;
242  }
243 
244  list.emplace_back(item);
245  page_num++;
246  }
247 
248  return list;
249  }
250 
255  {
256  return this->GetWidget<NWidgetCore>(WID_SB_PAGE_PANEL)->current_x - WD_FRAMETEXT_LEFT - WD_FRAMERECT_RIGHT;
257  }
258 
266  uint GetHeadHeight(int max_width) const
267  {
268  StoryPage *page = this->GetSelPage();
269  if (page == nullptr) return 0;
270  int height = 0;
271 
272  /* Title lines */
273  height += FONT_HEIGHT_NORMAL; // Date always use exactly one line.
274  SetDParamStr(0, page->title != nullptr ? page->title : this->selected_generic_title);
275  height += GetStringHeight(STR_STORY_BOOK_TITLE, max_width);
276 
277  return height;
278  }
279 
287  {
288  switch (pe.type) {
289  case SPET_GOAL: {
290  Goal *g = Goal::Get((GoalID) pe.referenced_id);
291  if (g == nullptr) return SPR_IMG_GOAL_BROKEN_REF;
292  return g->completed ? SPR_IMG_GOAL_COMPLETED : SPR_IMG_GOAL;
293  }
294  case SPET_LOCATION:
295  return SPR_IMG_VIEW_LOCATION;
296  default:
297  NOT_REACHED();
298  }
299  }
300 
307  uint GetPageElementHeight(const StoryPageElement &pe, int max_width)
308  {
309  switch (pe.type) {
310  case SPET_TEXT:
311  SetDParamStr(0, pe.text);
312  return GetStringHeight(STR_BLACK_RAW_STRING, max_width);
313  break;
314 
315  case SPET_GOAL:
316  case SPET_LOCATION: {
317  Dimension sprite_dim = GetSpriteSize(GetPageElementSprite(pe));
318  return sprite_dim.height;
319  break;
320  }
321  default:
322  NOT_REACHED();
323  }
324  return 0;
325  }
326 
333  {
334  StoryPage *page = this->GetSelPage();
335  if (page == nullptr) return 0;
336  int max_width = GetAvailablePageContentWidth();
337  uint element_vertical_dist = FONT_HEIGHT_NORMAL;
338 
339  /* Head */
340  uint height = GetHeadHeight(max_width);
341 
342  /* Body */
343  for (const StoryPageElement *pe : this->story_page_elements) {
344  height += element_vertical_dist;
345  height += GetPageElementHeight(*pe, max_width);
346  }
347 
348  return height;
349  }
350 
362  void DrawActionElement(int &y_offset, int width, int line_height, SpriteID action_sprite, StringID string_id = STR_JUST_RAW_STRING) const
363  {
364  Dimension sprite_dim = GetSpriteSize(action_sprite);
365  uint element_height = max(sprite_dim.height, (uint)line_height);
366 
367  uint sprite_top = y_offset + (element_height - sprite_dim.height) / 2;
368  uint text_top = y_offset + (element_height - line_height) / 2;
369 
370  DrawSprite(action_sprite, PAL_NONE, 0, sprite_top);
371  DrawString(sprite_dim.width + WD_FRAMETEXT_LEFT, width, text_top, string_id, TC_BLACK);
372 
373  y_offset += element_height;
374  }
375 
381  {
382  switch (pe.type) {
383  case SPET_TEXT:
384  /* Do nothing. */
385  break;
386 
387  case SPET_LOCATION:
388  if (_ctrl_pressed) {
390  } else {
392  }
393  break;
394 
395  case SPET_GOAL:
397  break;
398 
399  default:
400  NOT_REACHED();
401  }
402  }
403 
404 public:
406  {
407  this->CreateNestedTree();
408  this->vscroll = this->GetScrollbar(WID_SB_SCROLLBAR);
409  this->vscroll->SetStepSize(FONT_HEIGHT_NORMAL);
410 
411  /* Initialize page sort. */
412  this->story_pages.SetSortFuncs(StoryBookWindow::page_sorter_funcs);
413  this->story_pages.ForceRebuild();
414  this->BuildStoryPageList();
415  this->story_page_elements.SetSortFuncs(StoryBookWindow::page_element_sorter_funcs);
416  /* story_page_elements will get built by SetSelectedPage */
417 
418  this->FinishInitNested(window_number);
419  this->owner = (Owner)this->window_number;
420 
421  /* Initialize selected vars. */
422  this->selected_generic_title[0] = '\0';
423  this->selected_page_id = INVALID_STORY_PAGE;
424 
425  this->OnInvalidateData(-1);
426  }
427 
432  {
433  this->SetWidgetDisabledState(WID_SB_PREV_PAGE, story_pages.size() == 0 || this->IsFirstPageSelected());
434  this->SetWidgetDisabledState(WID_SB_NEXT_PAGE, story_pages.size() == 0 || this->IsLastPageSelected());
437  }
438 
443  void SetSelectedPage(uint16 page_index)
444  {
445  if (this->selected_page_id != page_index) {
446  this->selected_page_id = page_index;
447  this->RefreshSelectedPage();
449  }
450  }
451 
452  void SetStringParameters(int widget) const override
453  {
454  switch (widget) {
455  case WID_SB_SEL_PAGE: {
456  StoryPage *page = this->GetSelPage();
457  SetDParamStr(0, page != nullptr && page->title != nullptr ? page->title : this->selected_generic_title);
458  break;
459  }
460  case WID_SB_CAPTION:
461  if (this->window_number == INVALID_COMPANY) {
462  SetDParam(0, STR_STORY_BOOK_SPECTATOR_CAPTION);
463  } else {
464  SetDParam(0, STR_STORY_BOOK_CAPTION);
465  SetDParam(1, this->window_number);
466  }
467  break;
468  }
469  }
470 
471  void OnPaint() override
472  {
473  /* Detect if content has changed height. This can happen if a
474  * multi-line text contains eg. {COMPANY} and that company is
475  * renamed.
476  */
477  if (this->vscroll->GetCount() != this->GetContentHeight()) {
478  this->vscroll->SetCount(this->GetContentHeight());
481  }
482 
483  this->DrawWidgets();
484  }
485 
486  void DrawWidget(const Rect &r, int widget) const override
487  {
488  if (widget != WID_SB_PAGE_PANEL) return;
489 
490  StoryPage *page = this->GetSelPage();
491  if (page == nullptr) return;
492 
493  const int x = r.left + WD_FRAMETEXT_LEFT;
494  const int y = r.top + WD_FRAMETEXT_TOP;
495  const int right = r.right - WD_FRAMETEXT_RIGHT;
496  const int bottom = r.bottom - WD_FRAMETEXT_BOTTOM;
497 
498  /* Set up a clipping region for the panel. */
499  DrawPixelInfo tmp_dpi;
500  if (!FillDrawPixelInfo(&tmp_dpi, x, y, right - x + 1, bottom - y + 1)) return;
501 
502  DrawPixelInfo *old_dpi = _cur_dpi;
503  _cur_dpi = &tmp_dpi;
504 
505  /* Draw content (now coordinates given to Draw** are local to the new clipping region). */
506  int line_height = FONT_HEIGHT_NORMAL;
507  int y_offset = - this->vscroll->GetPosition();
508 
509  /* Date */
510  if (page->date != INVALID_DATE) {
511  SetDParam(0, page->date);
512  DrawString(0, right - x, y_offset, STR_JUST_DATE_LONG, TC_BLACK);
513  }
514  y_offset += line_height;
515 
516  /* Title */
517  SetDParamStr(0, page->title != nullptr ? page->title : this->selected_generic_title);
518  y_offset = DrawStringMultiLine(0, right - x, y_offset, bottom - y, STR_STORY_BOOK_TITLE, TC_BLACK, SA_TOP | SA_HOR_CENTER);
519 
520  /* Page elements */
521  for (const StoryPageElement *const pe : this->story_page_elements) {
522  y_offset += line_height; // margin to previous element
523 
524  switch (pe->type) {
525  case SPET_TEXT:
526  SetDParamStr(0, pe->text);
527  y_offset = DrawStringMultiLine(0, right - x, y_offset, bottom - y, STR_JUST_RAW_STRING, TC_BLACK, SA_TOP | SA_LEFT);
528  break;
529 
530  case SPET_GOAL: {
531  Goal *g = Goal::Get((GoalID) pe->referenced_id);
532  StringID string_id = g == nullptr ? STR_STORY_BOOK_INVALID_GOAL_REF : STR_JUST_RAW_STRING;
533  if (g != nullptr) SetDParamStr(0, g->text);
534  DrawActionElement(y_offset, right - x, line_height, GetPageElementSprite(*pe), string_id);
535  break;
536  }
537 
538  case SPET_LOCATION:
539  SetDParamStr(0, pe->text);
540  DrawActionElement(y_offset, right - x, line_height, GetPageElementSprite(*pe));
541  break;
542 
543  default: NOT_REACHED();
544  }
545  }
546 
547  /* Restore clipping region. */
548  _cur_dpi = old_dpi;
549  }
550 
551  void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override
552  {
553  if (widget != WID_SB_SEL_PAGE && widget != WID_SB_PAGE_PANEL) return;
554 
555  Dimension d;
556  d.height = FONT_HEIGHT_NORMAL;
557  d.width = 0;
558 
559  switch (widget) {
560  case WID_SB_SEL_PAGE: {
561 
562  /* Get max title width. */
563  for (uint16 i = 0; i < this->story_pages.size(); i++) {
564  const StoryPage *s = this->story_pages[i];
565 
566  if (s->title != nullptr) {
567  SetDParamStr(0, s->title);
568  } else {
569  SetDParamStr(0, this->selected_generic_title);
570  }
571  Dimension title_d = GetStringBoundingBox(STR_BLACK_RAW_STRING);
572 
573  if (title_d.width > d.width) {
574  d.width = title_d.width;
575  }
576  }
577 
578  d.width += padding.width;
579  d.height += padding.height;
580  *size = maxdim(*size, d);
581  break;
582  }
583 
584  case WID_SB_PAGE_PANEL: {
585  d.height *= 5;
586  d.height += padding.height + WD_FRAMETEXT_TOP + WD_FRAMETEXT_BOTTOM;
587  *size = maxdim(*size, d);
588  break;
589  }
590  }
591 
592  }
593 
594  void OnResize() override
595  {
597  this->vscroll->SetCount(this->GetContentHeight());
598  }
599 
600  void OnClick(Point pt, int widget, int click_count) override
601  {
602  switch (widget) {
603  case WID_SB_SEL_PAGE: {
604  DropDownList list = this->BuildDropDownList();
605  if (!list.empty()) {
606  /* Get the index of selected page. */
607  int selected = 0;
608  for (uint16 i = 0; i < this->story_pages.size(); i++) {
609  const StoryPage *p = this->story_pages[i];
610  if (p->index == this->selected_page_id) break;
611  selected++;
612  }
613 
614  ShowDropDownList(this, std::move(list), selected, widget);
615  }
616  break;
617  }
618 
619  case WID_SB_PREV_PAGE:
620  this->SelectPrevPage();
621  break;
622 
623  case WID_SB_NEXT_PAGE:
624  this->SelectNextPage();
625  break;
626 
627  case WID_SB_PAGE_PANEL: {
628  uint clicked_y = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_SB_PAGE_PANEL, WD_FRAMETEXT_TOP);
629  uint max_width = GetAvailablePageContentWidth();
630 
631  /* Skip head rows. */
632  uint head_height = this->GetHeadHeight(max_width);
633  if (clicked_y < head_height) return;
634 
635  /* Detect if a page element was clicked. */
636  uint y = head_height;
637  uint element_vertical_dist = FONT_HEIGHT_NORMAL;
638  for (const StoryPageElement *const pe : this->story_page_elements) {
639 
640  y += element_vertical_dist; // margin row
641 
642  uint content_height = GetPageElementHeight(*pe, max_width);
643  if (clicked_y >= y && clicked_y < y + content_height) {
644  this->OnPageElementClick(*pe);
645  return;
646  }
647 
648  y += content_height;
649  }
650  }
651  }
652  }
653 
654  void OnDropdownSelect(int widget, int index) override
655  {
656  if (widget != WID_SB_SEL_PAGE) return;
657 
658  /* index (which is set in BuildDropDownList) is the page id. */
659  this->SetSelectedPage(index);
660  }
661 
669  void OnInvalidateData(int data = 0, bool gui_scope = true) override
670  {
671  if (!gui_scope) return;
672 
673  /* If added/removed page, force rebuild. Sort order never change so just a
674  * re-sort is never needed.
675  */
676  if (data == -1) {
677  this->story_pages.ForceRebuild();
678  this->BuildStoryPageList();
679 
680  /* Was the last page removed? */
681  if (this->story_pages.size() == 0) {
682  this->selected_generic_title[0] = '\0';
683  }
684 
685  /* Verify page selection. */
686  if (!_story_page_pool.IsValidID(this->selected_page_id)) {
687  this->selected_page_id = INVALID_STORY_PAGE;
688  }
689  if (this->selected_page_id == INVALID_STORY_PAGE && this->story_pages.size() > 0) {
690  /* No page is selected, but there exist at least one available.
691  * => Select first page.
692  */
693  this->SetSelectedPage(this->story_pages[0]->index);
694  }
695 
696  this->SetWidgetDisabledState(WID_SB_SEL_PAGE, this->story_pages.size() == 0);
699  } else if (data >= 0 && this->selected_page_id == data) {
700  this->RefreshSelectedPage();
701  }
702  }
703 };
704 
705 GUIStoryPageList::SortFunction * const StoryBookWindow::page_sorter_funcs[] = {
707 };
708 
709 GUIStoryPageElementList::SortFunction * const StoryBookWindow::page_element_sorter_funcs[] = {
711 };
712 
713 static const NWidgetPart _nested_story_book_widgets[] = {
715  NWidget(WWT_CLOSEBOX, COLOUR_BROWN),
716  NWidget(WWT_CAPTION, COLOUR_BROWN, WID_SB_CAPTION), SetDataTip(STR_JUST_STRING, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
717  NWidget(WWT_SHADEBOX, COLOUR_BROWN),
718  NWidget(WWT_DEFSIZEBOX, COLOUR_BROWN),
719  NWidget(WWT_STICKYBOX, COLOUR_BROWN),
720  EndContainer(),
722  NWidget(NWID_VERTICAL), SetFill(1, 1),
725  NWidget(WWT_TEXTBTN, COLOUR_BROWN, WID_SB_PREV_PAGE), SetMinimalSize(100, 0), SetFill(0, 0), SetDataTip(STR_STORY_BOOK_PREV_PAGE, STR_STORY_BOOK_PREV_PAGE_TOOLTIP),
726  NWidget(NWID_BUTTON_DROPDOWN, COLOUR_BROWN, WID_SB_SEL_PAGE), SetMinimalSize(93, 12), SetFill(1, 0),
727  SetDataTip(STR_BLACK_RAW_STRING, STR_STORY_BOOK_SEL_PAGE_TOOLTIP), SetResize(1, 0),
728  NWidget(WWT_TEXTBTN, COLOUR_BROWN, WID_SB_NEXT_PAGE), SetMinimalSize(100, 0), SetFill(0, 0), SetDataTip(STR_STORY_BOOK_NEXT_PAGE, STR_STORY_BOOK_NEXT_PAGE_TOOLTIP),
729  EndContainer(),
730  EndContainer(),
731  NWidget(NWID_VERTICAL), SetFill(0, 1),
732  NWidget(NWID_VSCROLLBAR, COLOUR_BROWN, WID_SB_SCROLLBAR),
733  NWidget(WWT_RESIZEBOX, COLOUR_BROWN),
734  EndContainer(),
735  EndContainer(),
736 };
737 
738 static WindowDesc _story_book_desc(
739  WDP_CENTER, "view_story", 400, 300,
741  0,
742  _nested_story_book_widgets, lengthof(_nested_story_book_widgets)
743 );
744 
750 void ShowStoryBook(CompanyID company, uint16 page_id)
751 {
752  if (!Company::IsValidID(company)) company = (CompanyID)INVALID_COMPANY;
753 
754  StoryBookWindow *w = AllocateWindowDescFront<StoryBookWindow>(&_story_book_desc, company, true);
755  if (page_id != INVALID_STORY_PAGE) w->SetSelectedPage(page_id);
756 }
Functions related to OTTD&#39;s strings.
Owner
Enum for all companies/owners.
Definition: company_type.h:18
Page body.
Definition: story_widget.h:18
Base types for having sorted lists in GUIs.
void RebuildDone()
Notify the sortlist that the rebuild is done.
Definition of stuff that is very close to a company, like the company struct itself.
Caption of the window.
Definition: story_widget.h:16
Data about how and where to blit pixels.
Definition: gfx_type.h:154
Horizontally center the text.
Definition: gfx_func.h:95
ResizeInfo resize
Resize information.
Definition: window_gui.h:322
An element that references a tile along with a one-line text.
Definition: story_base.h:30
void OnResize() override
Called after the window got resized.
Definition: story_gui.cpp:594
static NWidgetPart SetResize(int16 dx, int16 dy)
Widget part function for setting the resize step.
Definition: widget_type.h:928
Window(WindowDesc *desc)
Empty constructor, initialization has been moved to InitNested() called from the constructor of the d...
Definition: window.cpp:1867
void SetWidgetDisabledState(byte widget_index, bool disab_stat)
Sets the enabled/disabled status of a widget.
Definition: window_gui.h:392
void SelectPrevPage()
Selects the previous available page before the currently selected page.
Definition: story_gui.cpp:186
High level window description.
Definition: window_gui.h:166
void DrawWidgets() const
Paint all widgets of a window.
Definition: widget.cpp:602
static Titem * Get(size_t index)
Returns Titem with given index.
Definition: pool_type.hpp:291
Functions related to dates.
Scrollbar data structure.
Definition: widget_type.h:587
uint16 GoalID
ID of a goal.
Definition: goal_type.h:31
void SetWidgetDirty(byte widget_index) const
Invalidate a widget, i.e.
Definition: window.cpp:597
Horizontal container.
Definition: widget_type.h:73
void UpdatePrevNextDisabledState()
Updates the disabled state of the prev/next buttons.
Definition: story_gui.cpp:431
void SetSortFuncs(SortFunction *const *n_funcs)
Hand the array of sort function pointers to the sort list.
void OnPageElementClick(const StoryPageElement &pe)
Internal event handler for when a page element is clicked.
Definition: story_gui.cpp:380
uint32 sort_value
A number that increases for every created story page element. Used for sorting. The id of a story pag...
Definition: story_base.h:45
bool IsValidID(size_t index)
Tests whether given index can be used to get valid (non-nullptr) Titem.
Definition: pool_type.hpp:121
Date date
Date when the page was created.
Definition: story_base.h:66
int GetSelPageNum() const
Get the page number of selected page.
Definition: story_gui.cpp:126
bool IsLastPageSelected()
Check if the selected page is also the last available page.
Definition: story_gui.cpp:152
Resize box (normally at bottom-right of a window)
Definition: widget_type.h:66
Struct about goals, current and completed.
Definition: goal_base.h:21
void ShowGoalsList(CompanyID company)
Open a goal list window.
Definition: goal_gui.cpp:345
void RefreshSelectedPage()
Updates the content of selected page.
Definition: story_gui.cpp:165
Tindex index
Index of this pool item.
Definition: pool_type.hpp:189
int GetStringHeight(const char *str, int maxw, FontSize fontsize)
Calculates height of string (in pixels).
Definition: gfx.cpp:547
Close box (at top-left of a window)
Definition: widget_type.h:67
Page selector.
Definition: story_widget.h:17
char * title
Title of story page.
Definition: story_base.h:69
void SetStringParameters(int widget) const override
Initialize string parameters for a widget.
Definition: story_gui.cpp:452
#define lastof(x)
Get the last element of an fixed size array.
Definition: depend.cpp:48
void SelectNextPage()
Selects the next available page after the currently selected page.
Definition: story_gui.cpp:206
void BuildStoryPageList()
(Re)Build story page list.
Definition: story_gui.cpp:50
static T max(const T a, const T b)
Returns the maximum of two values.
Definition: math_func.hpp:24
char selected_generic_title[255]
If the selected page doesn&#39;t have a custom title, this buffer is used to store a generic page title...
Definition: story_gui.cpp:44
Common string list item.
Definition: dropdown_type.h:39
uint GetContentHeight()
Get the total height of the content displayed in this window.
Definition: story_gui.cpp:332
void CreateNestedTree(bool fill_nested=true)
Perform the first part of the initialization of a nested widget tree.
Definition: window.cpp:1828
bool NeedRebuild() const
Check if a rebuild is needed.
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:1481
void OnPaint() override
The window must be repainted.
Definition: story_gui.cpp:471
void SetCount(int num)
Sets the number of elements in the list.
Definition: widget_type.h:668
Partial widget specification to allow NWidgets to be written nested.
Definition: widget_type.h:908
Functions related to (drawing on) viewports.
void ForceRebuild()
Force that a rebuild is needed.
Struct about story page elements.
Definition: story_base.h:44
Data structure for an opened window.
Definition: window_gui.h:276
bool _ctrl_pressed
Is Ctrl pressed?
Definition: gfx.cpp:35
void FinishInitNested(WindowNumber window_number=0)
Perform the second part of the initialization of a nested widget tree.
Definition: window.cpp:1844
uint32 referenced_id
Id of referenced object (location, goal etc.)
Definition: story_base.h:49
Bottom offset of the text of the frame.
Definition: window_gui.h:73
void SetDParamStr(uint n, const char *str)
This function is used to "bind" a C string to a OpenTTD dparam slot.
Definition: strings.cpp:279
Struct about stories, current and completed.
Definition: story_base.h:64
StoryPageID selected_page_id
Pool index of selected page.
Definition: story_gui.cpp:43
Default window size box (at top-right of a window, between WWT_SHADEBOX and WWT_STICKYBOX) ...
Definition: widget_type.h:63
int GetScrolledRowFromWidget(int clickpos, const Window *const w, int widget, int padding=0, int line_height=-1) const
Compute the row of a scrolled widget that a user clicked in.
Definition: widget.cpp:1957
Titem * Get(size_t index)
Returns Titem with given index.
Definition: pool_type.hpp:110
void SetSelectedPage(uint16 page_index)
Sets the selected page.
Definition: story_gui.cpp:443
GUIStoryPageElementList story_page_elements
Sorted list of page elements that belong to the current page.
Definition: story_gui.cpp:42
#define FONT_HEIGHT_NORMAL
Height of characters in the normal (FS_NORMAL) font.
Definition: gfx_func.h:176
static NWidgetPart SetDataTip(uint32 data, StringID tip)
Widget part function for setting the data and tooltip.
Definition: widget_type.h:1012
static NWidgetPart SetMinimalSize(int16 x, int16 y)
Widget part function for setting the minimal size.
Definition: widget_type.h:945
Definition of base types and functions in a cross-platform compatible way.
static const Date INVALID_DATE
Representation of an invalid date.
Definition: date_type.h:108
Top align the text.
Definition: gfx_func.h:99
A number of safeguards to prevent using unsafe methods.
void DrawWidget(const Rect &r, int widget) const override
Draw the contents of a nested widget.
Definition: story_gui.cpp:486
Geometry functions.
Simple depressed panel.
Definition: widget_type.h:48
const Scrollbar * GetScrollbar(uint widnum) const
Return the Scrollbar to a widget index.
Definition: window.cpp:309
SpriteID GetPageElementSprite(const StoryPageElement &pe) const
Decides which sprite to display for a given page element.
Definition: story_gui.cpp:286
StoryPageElementType type
Type of page element.
Definition: story_base.h:47
Center the window.
Definition: window_gui.h:155
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:1112
void OnInvalidateData(int data=0, bool gui_scope=true) override
Some data on this window has become invalid.
Definition: story_gui.cpp:669
uint GetPageElementHeight(const StoryPageElement &pe, int max_width)
Get the height in pixels used by a page element.
Definition: story_gui.cpp:307
Next button.
Definition: story_widget.h:21
Button with a drop-down.
Definition: widget_type.h:80
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:498
Right offset of the text of the frame.
Definition: window_gui.h:71
#define lengthof(x)
Return the length of an fixed size array.
Definition: depend.cpp:40
bool IsFirstPageSelected()
Check if the selected page is also the first available page.
Definition: story_gui.cpp:141
Top offset of the text of the frame.
Definition: window_gui.h:72
Left offset of the text of the frame.
Definition: window_gui.h:70
bool Sort(SortFunction *compare)
Sort the list.
void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override
Update size and resize step of a widget in the window.
Definition: story_gui.cpp:551
uint32 StringID
Numeric value that represents a string, independent of the selected language.
Definition: strings_type.h:16
uint32 sort_value
A number that increases for every created story page. Used for sorting. The id of a story page is the...
Definition: story_base.h:65
uint GetHeadHeight(int max_width) const
Counts how many pixels of height that are used by Date and Title (excluding marginal after Title...
Definition: story_gui.cpp:266
Scrollbar * vscroll
Scrollbar of the page text.
Definition: story_gui.cpp:39
void ShowExtraViewPortWindow(TileIndex tile=INVALID_TILE)
Show a new Extra Viewport window.
static const StoryPageID INVALID_STORY_PAGE
Constant representing a non-existing story page.
Definition: story_type.h:23
Dimension GetStringBoundingBox(const char *str, FontSize start_fontsize)
Return the string dimension in pixels.
Definition: gfx.cpp:700
An element that references a goal.
Definition: story_base.h:31
uint16 GetCount() const
Gets the number of elements in the list.
Definition: widget_type.h:611
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:38
Types related to the story widgets.
A text element.
Definition: story_base.h:29
Functions related to companies.
An invalid company.
Definition: company_type.h:30
static Pool::IterateWrapper< Titem > Iterate(size_t from=0)
Returns an iterable ensemble of all valid Titem.
Definition: pool_type.hpp:340
Window caption (window title between closebox and stickybox)
Definition: widget_type.h:59
uint GetAvailablePageContentWidth()
Get the width available for displaying content on the page panel.
Definition: story_gui.cpp:254
uint32 SpriteID
The number of a sprite, without mapping bits and colourtables.
Definition: gfx_type.h:17
StoryPage * GetSelPage() const
Get instance of selected page.
Definition: story_gui.cpp:116
void SetStepSize(uint16 stepsize)
Set the distance to scroll when using the buttons or the wheel.
Definition: widget_type.h:657
uint32 TileIndex
The index/ID of a Tile.
Definition: tile_type.h:78
static bool PageOrderSorter(const StoryPage *const &a, const StoryPage *const &b)
Sort story pages by order value.
Definition: story_gui.cpp:69
Story book; Window numbers:
Definition: window_type.h:289
void ShowStoryBook(CompanyID company, uint16 page_id)
Raise or create the story book window for company, at page page_id.
Definition: story_gui.cpp:750
GUIStoryPageList story_pages
Sorted list of pages.
Definition: story_gui.cpp:41
bool completed
Is the goal completed or not?
Definition: goal_base.h:27
Vertical container.
Definition: widget_type.h:75
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:997
Scrollbar of the goal list.
Definition: story_widget.h:19
Goal base class.
bool ScrollMainWindowToTile(TileIndex tile, bool instant)
Scrolls the viewport of the main window to a given location.
Definition: viewport.cpp:2396
Functions related to commands.
Coordinates of a point in 2D.
Dimension GetSpriteSize(SpriteID sprid, Point *offset, ZoomLevel zoom)
Get the size of a sprite.
Definition: gfx.cpp:770
List item containing a C char string.
Definition: dropdown_type.h:69
static bool IsValidID(size_t index)
Tests whether given index can be used to get valid (non-nullptr) Titem.
Definition: pool_type.hpp:280
Owner owner
The owner of the content shown in this window. Company colour is acquired from this variable...
Definition: window_gui.h:324
StoryPage base class.
Offset at right to draw the frame rectangular area.
Definition: window_gui.h:61
Sticky box (at top-right of a window, after WWT_DEFSIZEBOX)
Definition: widget_type.h:64
int width
width of the window (number of pixels to the right in x direction)
Definition: window_gui.h:319
void OnDropdownSelect(int widget, int index) override
A dropdown option associated to this window has been selected.
Definition: story_gui.cpp:654
static NWidgetPart SetFill(uint fill_x, uint fill_y)
Widget part function for setting filling.
Definition: widget_type.h:981
int32 WindowNumber
Number to differentiate different windows of the same class.
Definition: window_type.h:705
char * text
Static content text of page element.
Definition: story_base.h:50
void SetCapacityFromWidget(Window *w, int widget, int padding=0)
Set capacity of visible elements from the size and resize properties of a widget. ...
Definition: widget.cpp:1971
Specification of a rectangle with absolute coordinates of all edges.
Vertical scrollbar.
Definition: widget_type.h:82
WindowNumber window_number
Window number within the window class.
Definition: window_gui.h:312
char * text
Text of the goal.
Definition: goal_base.h:25
Left align the text.
Definition: gfx_func.h:94
Window functions not directly related to making/drawing windows.
DropDownList BuildDropDownList() const
Builds the page selector drop down list.
Definition: story_gui.cpp:227
String list item with parameters.
Definition: dropdown_type.h:56
GUI functions that shouldn&#39;t be here.
bool SortFunction(const T &, const T &)
Signature of sort function.
Definition: sortlist_type.h:49
uint16 StoryPageID
ID of a story page.
Definition: story_type.h:16
static bool PageElementOrderSorter(const StoryPageElement *const &a, const StoryPageElement *const &b)
Sort story page elements by order value.
Definition: story_gui.cpp:97
CompanyID company
StoryPage is for a specific company; INVALID_COMPANY if it is global.
Definition: story_base.h:67
static NWidgetPart SetScrollbar(int index)
Attach a scrollbar to a widget.
Definition: widget_type.h:1093
void BuildStoryPageElementList()
(Re)Build story page element list.
Definition: story_gui.cpp:75
Dimensions (a width and height) of a rectangle in 2D.
This file contains all sprite-related enums and defines.
Shade box (at top-right of a window, between WWT_DEBUGBOX and WWT_DEFSIZEBOX)
Definition: widget_type.h:62
void DrawActionElement(int &y_offset, int width, int line_height, SpriteID action_sprite, StringID string_id=STR_JUST_RAW_STRING) const
Draws a page element that is composed of a sprite to the left and a single line of text after that...
Definition: story_gui.cpp:362
Prev button.
Definition: story_widget.h:20
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:835
int height
Height of the window (number of pixels down in y direction)
Definition: window_gui.h:320
int DrawStringMultiLine(int left, int right, int top, int bottom, const char *str, TextColour colour, StringAlignment align, bool underline, FontSize fontsize)
Draw string, possibly over multiple lines.
Definition: gfx.cpp:621
(Toggle) Button with text
Definition: widget_type.h:53
uint16 GetPosition() const
Gets the position of the first visible element in the list.
Definition: widget_type.h:629
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:199
void OnClick(Point pt, int widget, int click_count) override
A click with the left mouse button has been made on the window.
Definition: story_gui.cpp:600