OpenTTD

story_gui.cpp
Go to the documentation of this file.
1 /* $Id: story_gui.cpp 27086 2014-12-18 18:22:23Z alberth $ */
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 "window_gui.h"
14 #include "strings_func.h"
15 #include "date_func.h"
16 #include "gui.h"
17 #include "story_base.h"
18 #include "core/geometry_func.hpp"
19 #include "company_func.h"
20 #include "command_func.h"
21 #include "widgets/dropdown_type.h"
22 #include "widgets/dropdown_func.h"
23 #include "sortlist_type.h"
24 #include "goal_base.h"
25 #include "viewport_func.h"
26 #include "window_func.h"
27 #include "company_base.h"
28
29 #include "widgets/story_widget.h"
30
31 #include "table/strings.h"
32 #include "table/sprites.h"
33
34 #include "safeguards.h"
35
36 typedef GUIList<const StoryPage*> GUIStoryPageList;
37 typedef GUIList<const StoryPageElement*> GUIStoryPageElementList;
38
39 struct StoryBookWindow : Window {
40 protected:
41 Scrollbar *vscroll;
42
43 GUIStoryPageList story_pages;
44 GUIStoryPageElementList story_page_elements;
45 StoryPageID selected_page_id;
46 char selected_generic_title[255];
47
48 static GUIStoryPageList::SortFunction * const page_sorter_funcs[];
49 static GUIStoryPageElementList::SortFunction * const page_element_sorter_funcs[];
50
52 void BuildStoryPageList()
53 {
54 if (this->story_pages.NeedRebuild()) {
55 this->story_pages.Clear();
56
57 const StoryPage *p;
58 FOR_ALL_STORY_PAGES(p) {
59 if (this->IsPageAvailable(p)) {
60 *this->story_pages.Append() = p;
61 }
62 }
63
64 this->story_pages.Compact();
65 this->story_pages.RebuildDone();
66 }
67
68 this->story_pages.Sort();
69 }
70
72 static int CDECL PageOrderSorter(const StoryPage * const *a, const StoryPage * const *b)
73 {
74 return (*a)->sort_value - (*b)->sort_value;
75 }
76
78 void BuildStoryPageElementList()
79 {
80 if (this->story_page_elements.NeedRebuild()) {
81 this->story_page_elements.Clear();
82
83 const StoryPage *p = GetSelPage();
84 if (p != NULL) {
85 const StoryPageElement *pe;
86 FOR_ALL_STORY_PAGE_ELEMENTS(pe) {
87 if (pe->page == p->index) {
88 *this->story_page_elements.Append() = pe;
89 }
90 }
91 }
92
93 this->story_page_elements.Compact();
94 this->story_page_elements.RebuildDone();
95 }
96
97 this->story_page_elements.Sort();
98 }
99
101 static int CDECL PageElementOrderSorter(const StoryPageElement * const *a, const StoryPageElement * const *b)
102 {
103 return (*a)->sort_value - (*b)->sort_value;
104 }
105
106 /*
107 * Checks if a given page should be visible in the story book.
108 * @param page The page to check.
109 * @return True if the page should be visible, otherwise false.
110 */
111 bool IsPageAvailable(const StoryPage *page) const
112 {
113 return page->company == INVALID_COMPANY || page->company == this->window_number;
114 }
115
120 StoryPage *GetSelPage() const
121 {
122 if (!_story_page_pool.IsValidID(selected_page_id)) return NULL;
123 return _story_page_pool.Get(selected_page_id);
124 }
125
130 int GetSelPageNum() const
131 {
132 int page_number = 0;
133 for (const StoryPage *const*iter = this->story_pages.Begin(); iter != this->story_pages.End(); iter++) {
134 const StoryPage *p = *iter;
135 if (p->index == this->selected_page_id) {
136 return page_number;
137 }
138 page_number++;
139 }
140 return -1;
141 }
142
146 bool IsFirstPageSelected()
147 {
148 /* Verify that the selected page exist. */
149 if (!_story_page_pool.IsValidID(this->selected_page_id)) return false;
150
151 return (*this->story_pages.Begin())->index == this->selected_page_id;
152 }
153
157 bool IsLastPageSelected()
158 {
159 /* Verify that the selected page exist. */
160 if (!_story_page_pool.IsValidID(this->selected_page_id)) return false;
161
162 if (this->story_pages.Length() <= 1) return true;
163 const StoryPage *last = *(this->story_pages.End() - 1);
164 return last->index == this->selected_page_id;
165 }
166
170 void RefreshSelectedPage()
171 {
172 /* Generate generic title if selected page have no custom title. */
173 StoryPage *page = this->GetSelPage();
174 if (page != NULL && page->title == NULL) {
175 SetDParam(0, GetSelPageNum() + 1);
176 GetString(selected_generic_title, STR_STORY_BOOK_GENERIC_PAGE_ITEM, lastof(selected_generic_title));
177 }
178
179 this->story_page_elements.ForceRebuild();
180 this->BuildStoryPageElementList();
181
182 this->vscroll->SetCount(this->GetContentHeight());
183 this->SetWidgetDirty(WID_SB_SCROLLBAR);
184 this->SetWidgetDirty(WID_SB_SEL_PAGE);
185 this->SetWidgetDirty(WID_SB_PAGE_PANEL);
186 }
187
191 void SelectPrevPage()
192 {
193 if (!_story_page_pool.IsValidID(this->selected_page_id)) return;
194
195 /* Find the last available page which is previous to the current selected page. */
196 const StoryPage *last_available;
197 last_available = NULL;
198 for (const StoryPage *const*iter = this->story_pages.Begin(); iter != this->story_pages.End(); iter++) {
199 const StoryPage *p = *iter;
200 if (p->index == this->selected_page_id) {
201 if (last_available == NULL) return; // No previous page available.
202 this->SetSelectedPage(last_available->index);
203 return;
204 }
205 last_available = p;
206 }
207 }
208
212 void SelectNextPage()
213 {
214 if (!_story_page_pool.IsValidID(this->selected_page_id)) return;
215
216 /* Find selected page. */
217 for (const StoryPage *const*iter = this->story_pages.Begin(); iter != this->story_pages.End(); iter++) {
218 const StoryPage *p = *iter;
219 if (p->index == this->selected_page_id) {
220 /* Select the page after selected page. */
221 iter++;
222 if (iter != this->story_pages.End()) {
223 this->SetSelectedPage((*iter)->index);
224 }
225 return;
226 }
227 }
228 }
229
233 DropDownList *BuildDropDownList() const
234 {
235 DropDownList *list = new DropDownList();
236 uint16 page_num = 1;
237 for (const StoryPage *const*iter = this->story_pages.Begin(); iter != this->story_pages.End(); iter++) {
238 const StoryPage *p = *iter;
239 bool current_page = p->index == this->selected_page_id;
240 DropDownListStringItem *item = NULL;
241 if (p->title != NULL) {
242 item = new DropDownListCharStringItem(p->title, p->index, current_page);
243 } else {
244 /* No custom title => use a generic page title with page number. */
245 DropDownListParamStringItem *str_item =
246 new DropDownListParamStringItem(STR_STORY_BOOK_GENERIC_PAGE_ITEM, p->index, current_page);
247 str_item->SetParam(0, page_num);
248 item = str_item;
249 }
250
251 *list->Append() = item;
252 page_num++;
253 }
254
255 /* Check if list is empty. */
256 if (list->Length() == 0) {
257 delete list;
258 list = NULL;
259 }
260
261 return list;
262 }
263
267 uint GetAvailablePageContentWidth()
268 {
269 return this->GetWidget<NWidgetCore>(WID_SB_PAGE_PANEL)->current_x - WD_FRAMETEXT_LEFT - WD_FRAMERECT_RIGHT;
270 }
271
279 uint GetHeadHeight(int max_width) const
280 {
281 StoryPage *page = this->GetSelPage();
282 if (page == NULL) return 0;
283 int height = 0;
284
285 /* Title lines */
286 height += FONT_HEIGHT_NORMAL; // Date always use exactly one line.
287 SetDParamStr(0, page->title != NULL ? page->title : this->selected_generic_title);
288 height += GetStringHeight(STR_STORY_BOOK_TITLE, max_width);
289
290 return height;
291 }
292
299 SpriteID GetPageElementSprite(const StoryPageElement &pe) const
300 {
301 switch (pe.type) {
302 case SPET_GOAL: {
303 Goal *g = Goal::Get((GoalID) pe.referenced_id);
304 if (g == NULL) return SPR_IMG_GOAL_BROKEN_REF;
305 return g->completed ? SPR_IMG_GOAL_COMPLETED : SPR_IMG_GOAL;
306 }
307 case SPET_LOCATION:
308 return SPR_IMG_VIEW_LOCATION;
309 default:
310 NOT_REACHED();
311 }
312 }
313
320 uint GetPageElementHeight(const StoryPageElement &pe, int max_width)
321 {
322 switch (pe.type) {
323 case SPET_TEXT:
324 SetDParamStr(0, pe.text);
325 return GetStringHeight(STR_BLACK_RAW_STRING, max_width);
326 break;
327
328 case SPET_GOAL:
329 case SPET_LOCATION: {
330 Dimension sprite_dim = GetSpriteSize(GetPageElementSprite(pe));
331 return sprite_dim.height;
332 break;
333 }
334 default:
335 NOT_REACHED();
336 }
337 return 0;
338 }
339
345 uint GetContentHeight()
346 {
347 StoryPage *page = this->GetSelPage();
348 if (page == NULL) return 0;
349 int max_width = GetAvailablePageContentWidth();
350 uint element_vertical_dist = FONT_HEIGHT_NORMAL;
351
352 /* Head */
353 uint height = GetHeadHeight(max_width);
354
355 /* Body */
356 for (const StoryPageElement **iter = this->story_page_elements.Begin(); iter != this->story_page_elements.End(); iter++) {
357 const StoryPageElement *pe = *iter;
358 height += element_vertical_dist;
359 height += GetPageElementHeight(*pe, max_width);
360 }
361
362 return height;
363 }
364
376 void DrawActionElement(int &y_offset, int width, int line_height, SpriteID action_sprite, StringID string_id = STR_JUST_RAW_STRING) const
377 {
378 Dimension sprite_dim = GetSpriteSize(action_sprite);
379 uint element_height = max(sprite_dim.height, (uint)line_height);
380
381 uint sprite_top = y_offset + (element_height - sprite_dim.height) / 2;
382 uint text_top = y_offset + (element_height - line_height) / 2;
383
384 DrawSprite(action_sprite, PAL_NONE, 0, sprite_top);
385 DrawString(sprite_dim.width + WD_FRAMETEXT_LEFT, width, text_top, string_id, TC_BLACK);
386
387 y_offset += element_height;
388 }
389
394 void OnPageElementClick(const StoryPageElement& pe)
395 {
396 switch (pe.type) {
397 case SPET_TEXT:
398 /* Do nothing. */
399 break;
400
401 case SPET_LOCATION:
402 if (_ctrl_pressed) {
403 ShowExtraViewPortWindow((TileIndex)pe.referenced_id);
404 } else {
405 ScrollMainWindowToTile((TileIndex)pe.referenced_id);
406 }
407 break;
408
409 case SPET_GOAL:
410 ShowGoalsList((CompanyID)this->window_number);
411 break;
412
413 default:
414 NOT_REACHED();
415 }
416 }
417
418 public:
419 StoryBookWindow(WindowDesc *desc, WindowNumber window_number) : Window(desc)
420 {
421 this->CreateNestedTree();
422 this->vscroll = this->GetScrollbar(WID_SB_SCROLLBAR);
423 this->vscroll->SetStepSize(FONT_HEIGHT_NORMAL);
424
425 /* Initalize page sort. */
426 this->story_pages.SetSortFuncs(StoryBookWindow::page_sorter_funcs);
427 this->story_pages.ForceRebuild();
428 this->BuildStoryPageList();
429 this->story_page_elements.SetSortFuncs(StoryBookWindow::page_element_sorter_funcs);
430 /* story_page_elements will get built by SetSelectedPage */
431
432 this->FinishInitNested(window_number);
433 this->owner = (Owner)this->window_number;
434
435 /* Initialize selected vars. */
436 this->selected_generic_title[0] = '\0';
437 this->selected_page_id = INVALID_STORY_PAGE;
438
439 this->OnInvalidateData(-1);
440 }
441
445 void UpdatePrevNextDisabledState()
446 {
447 this->SetWidgetDisabledState(WID_SB_PREV_PAGE, story_pages.Length() == 0 || this->IsFirstPageSelected());
448 this->SetWidgetDisabledState(WID_SB_NEXT_PAGE, story_pages.Length() == 0 || this->IsLastPageSelected());
449 this->SetWidgetDirty(WID_SB_PREV_PAGE);
450 this->SetWidgetDirty(WID_SB_NEXT_PAGE);
451 }
452
457 void SetSelectedPage(uint16 page_index)
458 {
459 if (this->selected_page_id != page_index) {
460 this->selected_page_id = page_index;
461 this->RefreshSelectedPage();
462 this->UpdatePrevNextDisabledState();
463 }
464 }
465
466 virtual void SetStringParameters(int widget) const
467 {
468 switch (widget) {
469 case WID_SB_SEL_PAGE: {
470 StoryPage *page = this->GetSelPage();
471 SetDParamStr(0, page != NULL && page->title != NULL ? page->title : this->selected_generic_title);
472 break;
473 }
474 case WID_SB_CAPTION:
475 if (this->window_number == INVALID_COMPANY) {
476 SetDParam(0, STR_STORY_BOOK_SPECTATOR_CAPTION);
477 } else {
478 SetDParam(0, STR_STORY_BOOK_CAPTION);
479 SetDParam(1, this->window_number);
480 }
481 break;
482 }
483 }
484
485 virtual void OnPaint()
486 {
487 /* Detect if content has changed height. This can happen if a
488 * multi-line text contains eg. {COMPANY} and that company is
489 * renamed.
490 */
491 if (this->vscroll->GetCount() != this->GetContentHeight()) {
492 this->vscroll->SetCount(this->GetContentHeight());
493 this->SetWidgetDirty(WID_SB_SCROLLBAR);
494 this->SetWidgetDirty(WID_SB_PAGE_PANEL);
495 }
496
497 this->DrawWidgets();
498 }
499
500 virtual void DrawWidget(const Rect &r, int widget) const
501 {
502 if (widget != WID_SB_PAGE_PANEL) return;
503
504 StoryPage *page = this->GetSelPage();
505 if (page == NULL) return;
506
507 const int x = r.left + WD_FRAMETEXT_LEFT;
508 const int y = r.top + WD_FRAMETEXT_TOP;
509 const int right = r.right - WD_FRAMETEXT_RIGHT;
510 const int bottom = r.bottom - WD_FRAMETEXT_BOTTOM;
511
512 /* Set up a clipping region for the panel. */
513 DrawPixelInfo tmp_dpi;
514 if (!FillDrawPixelInfo(&tmp_dpi, x, y, right - x + 1, bottom - y + 1)) return;
515
516 DrawPixelInfo *old_dpi = _cur_dpi;
517 _cur_dpi = &tmp_dpi;
518
519 /* Draw content (now coordinates given to Draw** are local to the new clipping region). */
520 int line_height = FONT_HEIGHT_NORMAL;
521 int y_offset = - this->vscroll->GetPosition();
522
523 /* Date */
524 if (page->date != INVALID_DATE) {
525 SetDParam(0, page->date);
526 DrawString(0, right - x, y_offset, STR_JUST_DATE_LONG, TC_BLACK);
527 }
528 y_offset += line_height;
529
530 /* Title */
531 SetDParamStr(0, page->title != NULL ? page->title : this->selected_generic_title);
532 y_offset = DrawStringMultiLine(0, right - x, y_offset, bottom - y, STR_STORY_BOOK_TITLE, TC_BLACK, SA_TOP | SA_HOR_CENTER);
533
534 /* Page elements */
535 for (const StoryPageElement *const*iter = this->story_page_elements.Begin(); iter != this->story_page_elements.End(); iter++) {
536 const StoryPageElement *const pe = *iter;
537 y_offset += line_height; // margin to previous element
538
539 switch (pe->type) {
540 case SPET_TEXT:
541 SetDParamStr(0, pe->text);
542 y_offset = DrawStringMultiLine(0, right - x, y_offset, bottom - y, STR_JUST_RAW_STRING, TC_BLACK, SA_TOP | SA_LEFT);
543 break;
544
545 case SPET_GOAL: {
546 Goal *g = Goal::Get((GoalID) pe->referenced_id);
547 StringID string_id = g == NULL ? STR_STORY_BOOK_INVALID_GOAL_REF : STR_JUST_RAW_STRING;
548 if (g != NULL) SetDParamStr(0, g->text);
549 DrawActionElement(y_offset, right - x, line_height, GetPageElementSprite(*pe), string_id);
550 break;
551 }
552
553 case SPET_LOCATION:
554 SetDParamStr(0, pe->text);
555 DrawActionElement(y_offset, right - x, line_height, GetPageElementSprite(*pe));
556 break;
557
558 default: NOT_REACHED();
559 }
560 }
561
562 /* Restore clipping region. */
563 _cur_dpi = old_dpi;
564 }
565
566 virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
567 {
568 if (widget != WID_SB_SEL_PAGE && widget != WID_SB_PAGE_PANEL) return;
569
570 Dimension d;
571 d.height = FONT_HEIGHT_NORMAL;
572 d.width = 0;
573
574 switch (widget) {
575 case WID_SB_SEL_PAGE: {
576
577 /* Get max title width. */
578 for (uint16 i = 0; i < this->story_pages.Length(); i++) {
579 const StoryPage *s = this->story_pages[i];
580
581 if (s->title != NULL) {
582 SetDParamStr(0, s->title);
583 } else {
584 SetDParamStr(0, this->selected_generic_title);
585 }
586 Dimension title_d = GetStringBoundingBox(STR_BLACK_RAW_STRING);
587
588 if (title_d.width > d.width) {
589 d.width = title_d.width;
590 }
591 }
592
593 d.width += padding.width;
594 d.height += padding.height;
595 *size = maxdim(*size, d);
596 break;
597 }
598
599 case WID_SB_PAGE_PANEL: {
600 d.height *= 5;
601 d.height += padding.height + WD_FRAMETEXT_TOP + WD_FRAMETEXT_BOTTOM;
602 *size = maxdim(*size, d);
603 break;
604 }
605 }
606
607 }
608
609 virtual void OnResize()
610 {
611 this->vscroll->SetCapacityFromWidget(this, WID_SB_PAGE_PANEL, WD_FRAMETEXT_TOP + WD_FRAMETEXT_BOTTOM);
612 this->vscroll->SetCount(this->GetContentHeight());
613 }
614
615 virtual void OnClick(Point pt, int widget, int click_count)
616 {
617 switch (widget) {
618 case WID_SB_SEL_PAGE: {
619 DropDownList *list = this->BuildDropDownList();
620 if (list != NULL) {
621 /* Get the index of selected page. */
622 int selected = 0;
623 for (uint16 i = 0; i < this->story_pages.Length(); i++) {
624 const StoryPage *p = this->story_pages[i];
625 if (p->index == this->selected_page_id) break;
626 selected++;
627 }
628
629 ShowDropDownList(this, list, selected, widget);
630 }
631 break;
632 }
633
634 case WID_SB_PREV_PAGE:
635 this->SelectPrevPage();
636 break;
637
638 case WID_SB_NEXT_PAGE:
639 this->SelectNextPage();
640 break;
641
642 case WID_SB_PAGE_PANEL: {
643 uint clicked_y = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_SB_PAGE_PANEL, WD_FRAMETEXT_TOP);
644 uint max_width = GetAvailablePageContentWidth();
645
646 /* Skip head rows. */
647 uint head_height = this->GetHeadHeight(max_width);
648 if (clicked_y < head_height) return;
649
650 /* Detect if a page element was clicked. */
651 uint y = head_height;
652 uint element_vertical_dist = FONT_HEIGHT_NORMAL;
653 for (const StoryPageElement *const*iter = this->story_page_elements.Begin(); iter != this->story_page_elements.End(); iter++) {
654 const StoryPageElement *const pe = *iter;
655
656 y += element_vertical_dist; // margin row
657
658 uint content_height = GetPageElementHeight(*pe, max_width);
659 if (clicked_y >= y && clicked_y < y + content_height) {
660 this->OnPageElementClick(*pe);
661 return;
662 }
663
664 y += content_height;
665 }
666 }
667 }
668 }
669
670 virtual void OnDropdownSelect(int widget, int index)
671 {
672 if (widget != WID_SB_SEL_PAGE) return;
673
674 /* index (which is set in BuildDropDownList) is the page id. */
675 this->SetSelectedPage(index);
676 }
677
685 virtual void OnInvalidateData(int data = 0, bool gui_scope = true)
686 {
687 if (!gui_scope) return;
688
689 /* If added/removed page, force rebuild. Sort order never change so just a
690 * re-sort is never needed.
691 */
692 if (data == -1) {
693 this->story_pages.ForceRebuild();
694 this->BuildStoryPageList();
695
696 /* Was the last page removed? */
697 if (this->story_pages.Length() == 0) {
698 this->selected_generic_title[0] = '\0';
699 }
700
701 /* Verify page selection. */
702 if (!_story_page_pool.IsValidID(this->selected_page_id)) {
703 this->selected_page_id = INVALID_STORY_PAGE;
704 }
705 if (this->selected_page_id == INVALID_STORY_PAGE && this->story_pages.Length() > 0) {
706 /* No page is selected, but there exist at least one available.
707 * => Select first page.
708 */
709 this->SetSelectedPage(this->story_pages[0]->index);
710 }
711
712 this->SetWidgetDisabledState(WID_SB_SEL_PAGE, this->story_pages.Length() == 0);
713 this->SetWidgetDirty(WID_SB_SEL_PAGE);
714 this->UpdatePrevNextDisabledState();
715 } else if (data >= 0 && this->selected_page_id == data) {
716 this->RefreshSelectedPage();
717 }
718 }
719 };
720
721 GUIStoryPageList::SortFunction * const StoryBookWindow::page_sorter_funcs[] = {
722 &PageOrderSorter,
723 };
724
725 GUIStoryPageElementList::SortFunction * const StoryBookWindow::page_element_sorter_funcs[] = {
726 &PageElementOrderSorter,
727 };
728
729 static const NWidgetPart _nested_story_book_widgets[] = {
730 NWidget(NWID_HORIZONTAL),
731 NWidget(WWT_CLOSEBOX, COLOUR_BROWN),
732 NWidget(WWT_CAPTION, COLOUR_BROWN, WID_SB_CAPTION), SetDataTip(STR_JUST_STRING, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
733 NWidget(WWT_SHADEBOX, COLOUR_BROWN),
734 NWidget(WWT_DEFSIZEBOX, COLOUR_BROWN),
735 NWidget(WWT_STICKYBOX, COLOUR_BROWN),
736 EndContainer(),
737 NWidget(NWID_HORIZONTAL), SetFill(1, 1),
738 NWidget(NWID_VERTICAL), SetFill(1, 1),
739 NWidget(WWT_PANEL, COLOUR_BROWN, WID_SB_PAGE_PANEL), SetResize(1, 1), SetScrollbar(WID_SB_SCROLLBAR), EndContainer(),
740 NWidget(NWID_HORIZONTAL),
741 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),
742 NWidget(NWID_BUTTON_DROPDOWN, COLOUR_BROWN, WID_SB_SEL_PAGE), SetMinimalSize(93, 12), SetFill(1, 0),
743 SetDataTip(STR_BLACK_RAW_STRING, STR_STORY_BOOK_SEL_PAGE_TOOLTIP), SetResize(1, 0),
744 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),
745 EndContainer(),
746 EndContainer(),
747 NWidget(NWID_VERTICAL), SetFill(0, 1),
748 NWidget(NWID_VSCROLLBAR, COLOUR_BROWN, WID_SB_SCROLLBAR),
749 NWidget(WWT_RESIZEBOX, COLOUR_BROWN),
750 EndContainer(),
751 EndContainer(),
752 };
753
754 static WindowDesc _story_book_desc(
755 WDP_CENTER, "view_story", 400, 300,
756 WC_STORY_BOOK, WC_NONE,
757 0,
758 _nested_story_book_widgets, lengthof(_nested_story_book_widgets)
759 );
760
766 void ShowStoryBook(CompanyID company, uint16 page_id)
767 {
768 if (!Company::IsValidID(company)) company = (CompanyID)INVALID_COMPANY;
769
770 StoryBookWindow *w = AllocateWindowDescFront<StoryBookWindow>(&_story_book_desc, company, true);
771 if (page_id != INVALID_STORY_PAGE) w->SetSelectedPage(page_id);
772 }
strings_func.h
Functions related to OTTD&#39;s strings.
WID_SB_PAGE_PANEL
Page body.
Definition: story_widget.h:20
sortlist_type.h
Base types for having sorted lists in GUIs.
GUIList< const StoryPage * >
GUIList::RebuildDone
void RebuildDone()
Notify the sortlist that the rebuild is done.
Definition: sortlist_type.h:397
company_base.h
Definition of stuff that is very close to a company, like the company struct itself.
WID_SB_CAPTION
Caption of the window.
Definition: story_widget.h:18
StoryBookWindow
Definition: story_gui.cpp:39
DrawPixelInfo
Data about how and where to blit pixels.
Definition: gfx_type.h:156
SA_HOR_CENTER
Horizontally center the text.
Definition: gfx_func.h:99
Window::resize
ResizeInfo resize
Resize information.
Definition: window_gui.h:317
SetResize
static NWidgetPart SetResize(int16 dx, int16 dy)
Widget part function for setting the resize step.
Definition: widget_type.h:930
Window::Window
Window(WindowDesc *desc)
Empty constructor, initialization has been moved to InitNested() called from the constructor of the d...
Definition: window.cpp:1843
Window::SetWidgetDisabledState
void SetWidgetDisabledState(byte widget_index, bool disab_stat)
Sets the enabled/disabled status of a widget.
Definition: window_gui.h:387
StoryBookWindow::SelectPrevPage
void SelectPrevPage()
Selects the previous available page before the currently selected page.
Definition: story_gui.cpp:191
StoryBookWindow::UpdateWidgetSize
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.
Definition: story_gui.cpp:566
WindowDesc
High level window description.
Definition: window_gui.h:168
StoryPageElement::page
StoryPageID page
Id of the page which the page element belongs to.
Definition: story_base.h:49
Window::DrawWidgets
void DrawWidgets() const
Paint all widgets of a window.
Definition: widget.cpp:604
Pool::PoolItem<&_goal_pool >::Get
static Titem * Get(size_t index)
Returns Titem with given index.
Definition: pool_type.hpp:246
date_func.h
Functions related to dates.
Scrollbar
Scrollbar data structure.
Definition: widget_type.h:589
GoalID
uint16 GoalID
ID of a goal.
Definition: goal_type.h:34
Window::SetWidgetDirty
void SetWidgetDirty(byte widget_index) const
Invalidate a widget, i.e.
Definition: window.cpp:577
NWID_HORIZONTAL
Horizontal container.
Definition: widget_type.h:75
StoryBookWindow::UpdatePrevNextDisabledState
void UpdatePrevNextDisabledState()
Updates the disabled state of the prev/next buttons.
Definition: story_gui.cpp:445
GUIList::SetSortFuncs
void SetSortFuncs(SortFunction *const *n_funcs)
Hand the array of sort function pointers to the sort list.
Definition: sortlist_type.h:286
StoryBookWindow::OnPageElementClick
void OnPageElementClick(const StoryPageElement &pe)
Internal event handler for when a page element is clicked.
Definition: story_gui.cpp:394
ShowDropDownList
void ShowDropDownList(Window *w, const DropDownList *list, int selected, int button, uint width, bool auto_width, bool instant_close)
Show a drop down list.
Definition: dropdown.cpp:421
StoryBookWindow::OnResize
virtual void OnResize()
Called after the window got resized.
Definition: story_gui.cpp:609
Pool::IsValidID
bool IsValidID(size_t index)
Tests whether given index can be used to get valid (non-NULL) Titem.
Definition: pool_type.hpp:122
StoryPage::date
Date date
Date when the page was created.
Definition: story_base.h:72
StoryBookWindow::GetSelPageNum
int GetSelPageNum() const
Get the page number of selected page.
Definition: story_gui.cpp:130
StoryBookWindow::IsLastPageSelected
bool IsLastPageSelected()
Check if the selected page is also the last available page.
Definition: story_gui.cpp:157
WWT_RESIZEBOX
Resize box (normally at bottom-right of a window)
Definition: widget_type.h:68
Goal
Struct about goals, current and completed.
Definition: goal_base.h:23
ShowGoalsList
void ShowGoalsList(CompanyID company)
Open a goal list window.
Definition: goal_gui.cpp:351
StoryBookWindow::PageElementOrderSorter
static int CDECL PageElementOrderSorter(const StoryPageElement *const *a, const StoryPageElement *const *b)
Sort story page elements by order value.
Definition: story_gui.cpp:101
StoryBookWindow::RefreshSelectedPage
void RefreshSelectedPage()
Updates the content of selected page.
Definition: story_gui.cpp:170
SmallVector::Clear
void Clear()
Remove all items from the list.
Definition: smallvec_type.hpp:98
SmallVector::Compact
void Compact()
Compact the list down to the smallest block size boundary.
Definition: smallvec_type.hpp:120
SmallVector::Begin
const T * Begin() const
Get the pointer to the first item (const)
Definition: smallvec_type.hpp:272
Pool::PoolItem::index
Tindex index
Index of this pool item.
Definition: pool_type.hpp:147
GetStringHeight
int GetStringHeight(const char *str, int maxw, FontSize fontsize)
Calculates height of string (in pixels).
Definition: gfx.cpp:547
WWT_CLOSEBOX
Close box (at top-left of a window)
Definition: widget_type.h:69
WID_SB_SEL_PAGE
Page selector.
Definition: story_widget.h:19
StoryBookWindow::BuildDropDownList
DropDownList * BuildDropDownList() const
Builds the page selector drop down list.
Definition: story_gui.cpp:233
StoryPage::title
char * title
Title of story page.
Definition: story_base.h:75
lastof
#define lastof(x)
Get the last element of an fixed size array.
Definition: depend.cpp:50
StoryBookWindow::SelectNextPage
void SelectNextPage()
Selects the next available page after the currently selected page.
Definition: story_gui.cpp:212
StoryBookWindow::BuildStoryPageList
void BuildStoryPageList()
(Re)Build story page list.
Definition: story_gui.cpp:52
max
static T max(const T a, const T b)
Returns the maximum of two values.
Definition: math_func.hpp:26
StoryBookWindow::selected_generic_title
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:46
DropDownListStringItem
Common string list item.
Definition: dropdown_type.h:41
StoryBookWindow::GetContentHeight
uint GetContentHeight()
Get the total height of the content displayed in this window.
Definition: story_gui.cpp:345
SmallVector::End
const T * End() const
Get the pointer behind the last valid item (const)
Definition: smallvec_type.hpp:292
Window::CreateNestedTree
void CreateNestedTree(bool fill_nested=true)
Perform the first part of the initialization of a nested widget tree.
Definition: window.cpp:1804
GUIList::NeedRebuild
bool NeedRebuild() const
Check if a rebuild is needed.
Definition: sortlist_type.h:379
window_gui.h
Functions, definitions and such used only by the GUI.
FillDrawPixelInfo
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
SmallVector::Append
T * Append(uint to_add=1)
Append an item and return it.
Definition: smallvec_type.hpp:134
Scrollbar::SetCount
void SetCount(int num)
Sets the number of elements in the list.
Definition: widget_type.h:670
NWidgetPart
Partial widget specification to allow NWidgets to be written nested.
Definition: widget_type.h:910
viewport_func.h
Functions related to (drawing on) viewports.
GUIList::ForceRebuild
void ForceRebuild()
Force that a rebuild is needed.
Definition: sortlist_type.h:387
StoryPageElement
Struct about story page elements.
Definition: story_base.h:47
Window
Data structure for an opened window.
Definition: window_gui.h:271
_ctrl_pressed
bool _ctrl_pressed
Is Ctrl pressed?
Definition: gfx.cpp:36
Window::FinishInitNested
void FinishInitNested(WindowNumber window_number=0)
Perform the second part of the initialization of a nested widget tree.
Definition: window.cpp:1820
StoryPageElement::referenced_id
uint32 referenced_id
Id of referenced object (location, goal etc.)
Definition: story_base.h:52
WD_FRAMETEXT_BOTTOM
Bottom offset of the text of the frame.
Definition: window_gui.h:75
SetDParamStr
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
StoryBookWindow::OnPaint
virtual void OnPaint()
The window must be repainted.
Definition: story_gui.cpp:485
StoryPage
Struct about stories, current and completed.
Definition: story_base.h:70
StoryBookWindow::selected_page_id
StoryPageID selected_page_id
Pool index of selected page.
Definition: story_gui.cpp:45
WWT_DEFSIZEBOX
Default window size box (at top-right of a window, between WWT_SHADEBOX and WWT_STICKYBOX) ...
Definition: widget_type.h:65
SmallVector::Length
uint Length() const
Get the number of items in the list.
Definition: smallvec_type.hpp:262
Scrollbar::GetScrolledRowFromWidget
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:1959
Pool::Get
Titem * Get(size_t index)
Returns Titem with given index.
Definition: pool_type.hpp:111
StoryBookWindow::SetSelectedPage
void SetSelectedPage(uint16 page_index)
Sets the selected page.
Definition: story_gui.cpp:457
StoryBookWindow::story_page_elements
GUIStoryPageElementList story_page_elements
Sorted list of page elements that belong to the current page.
Definition: story_gui.cpp:44
FONT_HEIGHT_NORMAL
#define FONT_HEIGHT_NORMAL
Height of characters in the normal (FS_NORMAL) font.
Definition: gfx_func.h:180
SetDataTip
static NWidgetPart SetDataTip(uint32 data, StringID tip)
Widget part function for setting the data and tooltip.
Definition: widget_type.h:1014
AutoDeleteSmallVector
Simple vector template class, with automatic delete.
Definition: smallvec_type.hpp:401
SetMinimalSize
static NWidgetPart SetMinimalSize(int16 x, int16 y)
Widget part function for setting the minimal size.
Definition: widget_type.h:947
stdafx.h
Definition of base types and functions in a cross-platform compatible way.
INVALID_DATE
static const Date INVALID_DATE
Representation of an invalid date.
Definition: date_type.h:110
SA_TOP
Top align the text.
Definition: gfx_func.h:103
safeguards.h
A number of safeguards to prevent using unsafe methods.
StoryBookWindow::OnInvalidateData
virtual void OnInvalidateData(int data=0, bool gui_scope=true)
Some data on this window has become invalid.
Definition: story_gui.cpp:685
StoryBookWindow::OnClick
virtual void OnClick(Point pt, int widget, int click_count)
A click with the left mouse button has been made on the window.
Definition: story_gui.cpp:615
geometry_func.hpp
Geometry functions.
WWT_PANEL
Simple depressed panel.
Definition: widget_type.h:50
StoryBookWindow::OnDropdownSelect
virtual void OnDropdownSelect(int widget, int index)
A dropdown option associated to this window has been selected.
Definition: story_gui.cpp:670
Window::GetScrollbar
const Scrollbar * GetScrollbar(uint widnum) const
Return the Scrollbar to a widget index.
Definition: window.cpp:307
StoryBookWindow::GetPageElementSprite
SpriteID GetPageElementSprite(const StoryPageElement &pe) const
Decides which sprite to display for a given page element.
Definition: story_gui.cpp:299
WDP_CENTER
Center the window.
Definition: window_gui.h:157
StoryBookWindow::SetStringParameters
virtual void SetStringParameters(int widget) const
Initialize string parameters for a widget.
Definition: story_gui.cpp:466
NWidget
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
StoryBookWindow::GetPageElementHeight
uint GetPageElementHeight(const StoryPageElement &pe, int max_width)
Get the height in pixels used by a page element.
Definition: story_gui.cpp:320
WID_SB_NEXT_PAGE
Next button.
Definition: story_widget.h:23
NWID_BUTTON_DROPDOWN
Button with a drop-down.
Definition: widget_type.h:82
DrawString
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
WD_FRAMETEXT_RIGHT
Right offset of the text of the frame.
Definition: window_gui.h:73
lengthof
#define lengthof(x)
Return the length of an fixed size array.
Definition: depend.cpp:42
StoryBookWindow::IsFirstPageSelected
bool IsFirstPageSelected()
Check if the selected page is also the first available page.
Definition: story_gui.cpp:146
WD_FRAMETEXT_TOP
Top offset of the text of the frame.
Definition: window_gui.h:74
WD_FRAMETEXT_LEFT
Left offset of the text of the frame.
Definition: window_gui.h:72
dropdown_type.h
Types related to the drop down widget.
GUIList::Sort
bool Sort(SortFunction *compare)
Sort the list.
Definition: sortlist_type.h:256
StringID
uint32 StringID
Numeric value that represents a string, independent of the selected language.
Definition: strings_type.h:18
StoryPage::company
CompanyByte company
StoryPage is for a specific company; INVALID_COMPANY if it is global.
Definition: story_base.h:73
StoryBookWindow::DrawWidget
virtual void DrawWidget(const Rect &r, int widget) const
Draw the contents of a nested widget.
Definition: story_gui.cpp:500
StoryBookWindow::GetHeadHeight
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:279
StoryBookWindow::vscroll
Scrollbar * vscroll
Scrollbar of the page text.
Definition: story_gui.cpp:41
ShowExtraViewPortWindow
void ShowExtraViewPortWindow(TileIndex tile=INVALID_TILE)
Show a new Extra Viewport window.
Definition: viewport_gui.cpp:170
INVALID_STORY_PAGE
static const StoryPageID INVALID_STORY_PAGE
Constant representing a non-existing story page.
Definition: story_type.h:25
GetStringBoundingBox
Dimension GetStringBoundingBox(const char *str, FontSize start_fontsize)
Return the string dimension in pixels.
Definition: gfx.cpp:699
Scrollbar::GetCount
uint16 GetCount() const
Gets the number of elements in the list.
Definition: widget_type.h:613
maxdim
Dimension maxdim(const Dimension &d1, const Dimension &d2)
Compute bounding box of both dimensions.
Definition: geometry_func.cpp:24
WC_NONE
No window, redirects to WC_MAIN_WINDOW.
Definition: window_type.h:40
story_widget.h
Types related to the story widgets.
company_func.h
Functions related to companies.
WWT_CAPTION
Window caption (window title between closebox and stickybox)
Definition: widget_type.h:61
StoryBookWindow::GetAvailablePageContentWidth
uint GetAvailablePageContentWidth()
Get the width available for displaying content on the page panel.
Definition: story_gui.cpp:267
SpriteID
uint32 SpriteID
The number of a sprite, without mapping bits and colourtables.
Definition: gfx_type.h:19
StoryBookWindow::GetSelPage
StoryPage * GetSelPage() const
Get instance of selected page.
Definition: story_gui.cpp:120
Scrollbar::SetStepSize
void SetStepSize(uint16 stepsize)
Set the distance to scroll when using the buttons or the wheel.
Definition: widget_type.h:659
TileIndex
uint32 TileIndex
The index/ID of a Tile.
Definition: tile_type.h:80
WC_STORY_BOOK
Story book; Window numbers:
Definition: window_type.h:291
ShowStoryBook
void ShowStoryBook(CompanyID company, uint16 page_id)
Raise or create the story book window for company, at page page_id.
Definition: story_gui.cpp:766
StoryBookWindow::story_pages
GUIStoryPageList story_pages
Sorted list of pages.
Definition: story_gui.cpp:43
Goal::completed
bool completed
Is the goal completed or not?
Definition: goal_base.h:29
NWID_VERTICAL
Vertical container.
Definition: widget_type.h:77
GUIList::SortFunction
int CDECL SortFunction(const T *, const T *)
Signature of sort function.
Definition: sortlist_type.h:52
EndContainer
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
WID_SB_SCROLLBAR
Scrollbar of the goal list.
Definition: story_widget.h:21
goal_base.h
Goal base class.
dropdown_func.h
Functions related to the drop down widget.
ScrollMainWindowToTile
bool ScrollMainWindowToTile(TileIndex tile, bool instant)
Scrolls the viewport of the main window to a given location.
Definition: viewport.cpp:2268
SPET_TEXT
A text element.
Definition: story_base.h:31
SPET_GOAL
An element that references a goal.
Definition: story_base.h:33
command_func.h
Functions related to commands.
StoryBookWindow::PageOrderSorter
static int CDECL PageOrderSorter(const StoryPage *const *a, const StoryPage *const *b)
Sort story pages by order value.
Definition: story_gui.cpp:72
Point
Coordinates of a point in 2D.
Definition: geometry_type.hpp:28
GetSpriteSize
Dimension GetSpriteSize(SpriteID sprid, Point *offset, ZoomLevel zoom)
Get the size of a sprite.
Definition: gfx.cpp:768
DropDownListCharStringItem
List item containing a C char string.
Definition: dropdown_type.h:73
Pool::PoolItem<&_company_pool >::IsValidID
static bool IsValidID(size_t index)
Tests whether given index can be used to get valid (non-NULL) Titem.
Definition: pool_type.hpp:235
Window::owner
Owner owner
The owner of the content shown in this window. Company colour is acquired from this variable...
Definition: window_gui.h:319
story_base.h
StoryPage base class.
WD_FRAMERECT_RIGHT
Offset at right to draw the frame rectangular area.
Definition: window_gui.h:63
WWT_STICKYBOX
Sticky box (at top-right of a window, after WWT_DEFSIZEBOX)
Definition: widget_type.h:66
Window::width
int width
width of the window (number of pixels to the right in x direction)
Definition: window_gui.h:314
SPET_LOCATION
An element that references a tile along with a one-line text.
Definition: story_base.h:32
SetFill
static NWidgetPart SetFill(uint fill_x, uint fill_y)
Widget part function for setting filling.
Definition: widget_type.h:983
WindowNumber
int32 WindowNumber
Number to differentiate different windows of the same class.
Definition: window_type.h:695
StoryPageElement::text
char * text
Static content text of page element.
Definition: story_base.h:53
StoryPageElement::type
StoryPageElementTypeByte type
Type of page element.
Definition: story_base.h:50
Scrollbar::SetCapacityFromWidget
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:1973
Rect
Specification of a rectangle with absolute coordinates of all edges.
Definition: geometry_type.hpp:40
NWID_VSCROLLBAR
Vertical scrollbar.
Definition: widget_type.h:84
Window::window_number
WindowNumber window_number
Window number within the window class.
Definition: window_gui.h:307
Goal::text
char * text
Text of the goal.
Definition: goal_base.h:27
SA_LEFT
Left align the text.
Definition: gfx_func.h:98
Owner
Owner
Enum for all companies/owners.
Definition: company_type.h:20
window_func.h
Window functions not directly related to making/drawing windows.
DropDownListParamStringItem
String list item with parameters.
Definition: dropdown_type.h:59
gui.h
GUI functions that shouldn&#39;t be here.
StoryPageID
uint16 StoryPageID
ID of a story page.
Definition: story_type.h:18
INVALID_COMPANY
An invalid company.
Definition: company_type.h:32
SetScrollbar
static NWidgetPart SetScrollbar(int index)
Attach a scrollbar to a widget.
Definition: widget_type.h:1095
StoryBookWindow::BuildStoryPageElementList
void BuildStoryPageElementList()
(Re)Build story page element list.
Definition: story_gui.cpp:78
Dimension
Dimensions (a width and height) of a rectangle in 2D.
Definition: geometry_type.hpp:34
sprites.h
This file contains all sprite-related enums and defines.
WWT_SHADEBOX
Shade box (at top-right of a window, between WWT_DEBUGBOX and WWT_DEFSIZEBOX)
Definition: widget_type.h:64
StoryBookWindow::DrawActionElement
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:376
WID_SB_PREV_PAGE
Prev button.
Definition: story_widget.h:22
DrawSprite
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
Window::height
int height
Height of the window (number of pixels down in y direction)
Definition: window_gui.h:315
DropDownList
AutoDeleteSmallVector< const DropDownListItem *, 4 > DropDownList
A drop down list is a collection of drop down list items.
Definition: dropdown_type.h:86
DrawStringMultiLine
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:620
WWT_TEXTBTN
(Toggle) Button with text
Definition: widget_type.h:55
Scrollbar::GetPosition
uint16 GetPosition() const
Gets the position of the first visible element in the list.
Definition: widget_type.h:631
SetDParam
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