OpenTTD Source 20241224-master-gf74b0cf984
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 "gui.h"
14#include "story_base.h"
16#include "company_func.h"
17#include "command_func.h"
18#include "dropdown_type.h"
19#include "dropdown_func.h"
20#include "sortlist_type.h"
21#include "goal_base.h"
22#include "viewport_func.h"
23#include "window_func.h"
24#include "company_base.h"
25#include "tilehighlight_func.h"
26#include "vehicle_base.h"
27#include "story_cmd.h"
28
30
31#include "table/strings.h"
32#include "table/sprites.h"
33
34#include "safeguards.h"
35
36static CursorID TranslateStoryPageButtonCursor(StoryPageButtonCursor cursor);
37
40
42protected:
44 const StoryPageElement *pe;
45 Rect bounds;
46 };
47 typedef std::vector<LayoutCacheElement> LayoutCache;
48
49 enum class ElementFloat {
50 None,
51 Left,
52 Right,
53 };
54
56 mutable LayoutCache layout_cache;
57
62
64
65 static const std::initializer_list<GUIStoryPageList::SortFunction * const> page_sorter_funcs;
66 static const std::initializer_list<GUIStoryPageElementList::SortFunction * const> page_element_sorter_funcs;
67
70 {
71 if (this->story_pages.NeedRebuild()) {
72 this->story_pages.clear();
73
74 for (const StoryPage *p : StoryPage::Iterate()) {
75 if (this->IsPageAvailable(p)) {
76 this->story_pages.push_back(p);
77 }
78 }
79
80 this->story_pages.RebuildDone();
81 }
82
83 this->story_pages.Sort();
84 }
85
87 static bool PageOrderSorter(const StoryPage * const &a, const StoryPage * const &b)
88 {
89 return a->sort_value < b->sort_value;
90 }
91
94 {
95 if (this->story_page_elements.NeedRebuild()) {
96 this->story_page_elements.clear();
97
98 const StoryPage *p = GetSelPage();
99 if (p != nullptr) {
100 for (const StoryPageElement *pe : StoryPageElement::Iterate()) {
101 if (pe->page == p->index) {
102 this->story_page_elements.push_back(pe);
103 }
104 }
105 }
106
107 this->story_page_elements.RebuildDone();
108 }
109
110 this->story_page_elements.Sort();
112 }
113
115 static bool PageElementOrderSorter(const StoryPageElement * const &a, const StoryPageElement * const &b)
116 {
117 return a->sort_value < b->sort_value;
118 }
119
120 /*
121 * Checks if a given page should be visible in the story book.
122 * @param page The page to check.
123 * @return True if the page should be visible, otherwise false.
124 */
125 bool IsPageAvailable(const StoryPage *page) const
126 {
127 return page->company == INVALID_COMPANY || page->company == this->window_number;
128 }
129
135 {
136 if (!_story_page_pool.IsValidID(selected_page_id)) return nullptr;
137 return _story_page_pool.Get(selected_page_id);
138 }
139
144 int GetSelPageNum() const
145 {
146 int page_number = 0;
147 for (const StoryPage *p : this->story_pages) {
148 if (p->index == this->selected_page_id) {
149 return page_number;
150 }
151 page_number++;
152 }
153 return -1;
154 }
155
160 {
161 /* Verify that the selected page exist. */
162 if (!_story_page_pool.IsValidID(this->selected_page_id)) return false;
163
164 return this->story_pages.front()->index == this->selected_page_id;
165 }
166
171 {
172 /* Verify that the selected page exist. */
173 if (!_story_page_pool.IsValidID(this->selected_page_id)) return false;
174
175 if (this->story_pages.size() <= 1) return true;
176 const StoryPage *last = this->story_pages.back();
177 return last->index == this->selected_page_id;
178 }
179
184 {
185 /* Generate generic title if selected page have no custom title. */
186 StoryPage *page = this->GetSelPage();
187 if (page != nullptr && page->title.empty()) {
188 SetDParam(0, GetSelPageNum() + 1);
190 }
191
192 this->story_page_elements.ForceRebuild();
194
195 if (this->active_button_id != INVALID_STORY_PAGE_ELEMENT) ResetObjectToPlace();
196
197 this->vscroll->SetCount(this->GetContentHeight());
201 }
202
207 {
208 if (!_story_page_pool.IsValidID(this->selected_page_id)) return;
209
210 /* Find the last available page which is previous to the current selected page. */
212 last_available = nullptr;
213 for (const StoryPage *p : this->story_pages) {
214 if (p->index == this->selected_page_id) {
215 if (last_available == nullptr) return; // No previous page available.
216 this->SetSelectedPage(last_available->index);
217 return;
218 }
219 last_available = p;
220 }
221 }
222
227 {
228 if (!_story_page_pool.IsValidID(this->selected_page_id)) return;
229
230 /* Find selected page. */
231 for (auto iter = this->story_pages.begin(); iter != this->story_pages.end(); iter++) {
232 const StoryPage *p = *iter;
233 if (p->index == this->selected_page_id) {
234 /* Select the page after selected page. */
235 iter++;
236 if (iter != this->story_pages.end()) {
237 this->SetSelectedPage((*iter)->index);
238 }
239 return;
240 }
241 }
242 }
243
248 {
249 DropDownList list;
250 uint16_t page_num = 1;
251 for (const StoryPage *p : this->story_pages) {
252 bool current_page = p->index == this->selected_page_id;
253 if (!p->title.empty()) {
254 list.push_back(MakeDropDownListStringItem(p->title, p->index, current_page));
255 } else {
256 /* No custom title => use a generic page title with page number. */
258 list.push_back(MakeDropDownListStringItem(STR_STORY_BOOK_GENERIC_PAGE_ITEM, p->index, current_page));
259 }
260 page_num++;
261 }
262
263 return list;
264 }
265
273
281 uint GetHeadHeight(int max_width) const
282 {
283 StoryPage *page = this->GetSelPage();
284 if (page == nullptr) return 0;
285 int height = 0;
286
287 /* Title lines */
288 height += GetCharacterHeight(FS_NORMAL); // Date always use exactly one line.
289 SetDParamStr(0, !page->title.empty() ? page->title : this->selected_generic_title);
291
292 return height;
293 }
294
302 {
303 switch (pe.type) {
304 case SPET_GOAL: {
306 if (g == nullptr) return SPR_IMG_GOAL_BROKEN_REF;
307 return g->completed ? SPR_IMG_GOAL_COMPLETED : SPR_IMG_GOAL;
308 }
309 case SPET_LOCATION:
310 return SPR_IMG_VIEW_LOCATION;
311 default:
312 NOT_REACHED();
313 }
314 }
315
323 {
324 switch (pe.type) {
325 case SPET_TEXT:
326 SetDParamStr(0, pe.text);
328
329 case SPET_GOAL:
330 case SPET_LOCATION: {
332 return sprite_dim.height;
333 }
334
335 case SPET_BUTTON_PUSH:
336 case SPET_BUTTON_TILE:
337 case SPET_BUTTON_VEHICLE: {
340 }
341
342 default:
343 NOT_REACHED();
344 }
345 return 0;
346 }
347
353 ElementFloat GetPageElementFloat(const StoryPageElement &pe) const
354 {
355 switch (pe.type) {
356 case SPET_BUTTON_PUSH:
357 case SPET_BUTTON_TILE:
358 case SPET_BUTTON_VEHICLE: {
360 if (flags & SPBF_FLOAT_LEFT) return ElementFloat::Left;
361 if (flags & SPBF_FLOAT_RIGHT) return ElementFloat::Right;
362 return ElementFloat::None;
363 }
364
365 default:
366 return ElementFloat::None;
367 }
368 }
369
376 {
377 switch (pe.type) {
378 case SPET_BUTTON_PUSH:
379 case SPET_BUTTON_TILE:
380 case SPET_BUTTON_VEHICLE: {
383 }
384
385 default:
386 NOT_REACHED(); // only buttons can float
387 }
388 }
389
392 {
393 this->layout_cache.clear();
394 }
395
398 {
399 /* Assume if the layout cache has contents it is valid */
400 if (!this->layout_cache.empty()) return;
401
402 StoryPage *page = this->GetSelPage();
403 if (page == nullptr) return;
406
407 /* Make space for the header */
409
410 /* Current bottom of left/right column */
411 int left_y = main_y;
412 int right_y = main_y;
413 /* Current width of left/right column, 0 indicates no content in column */
414 int left_width = 0;
415 int right_width = 0;
416 /* Indexes into element cache for yet unresolved floats */
417 std::vector<size_t> left_floats;
418 std::vector<size_t> right_floats;
419
420 /* Build layout */
421 for (const StoryPageElement *pe : this->story_page_elements) {
422 ElementFloat fl = this->GetPageElementFloat(*pe);
423
424 if (fl == ElementFloat::None) {
425 /* Verify available width */
427 int left_offset = (left_width == 0) ? 0 : (left_width + element_dist);
428 int right_offset = (right_width == 0) ? 0 : (right_width + element_dist);
430 /* Width of floats leave too little for main content, push down */
431 main_y = std::max(main_y, left_y);
432 main_y = std::max(main_y, right_y);
435 /* Do not add element_dist here, to keep together elements which were supposed to float besides each other. */
436 }
437 /* Determine height */
440 /* Check for button that needs extra margin */
441 if (left_offset == 0 && right_offset == 0) {
442 switch (pe->type) {
443 case SPET_BUTTON_PUSH:
444 case SPET_BUTTON_TILE:
447 break;
448 default:
449 break;
450 }
451 }
452 /* Position element in main column */
453 LayoutCacheElement ce{ pe, {} };
454 ce.bounds.left = left_offset;
455 ce.bounds.right = max_width - right_offset;
456 ce.bounds.top = main_y;
457 main_y += height;
458 ce.bounds.bottom = main_y;
459 this->layout_cache.push_back(ce);
461 /* Clear all floats */
463 left_y = right_y = main_y = std::max({main_y, left_y, right_y});
464 left_floats.clear();
465 right_floats.clear();
466 } else {
467 /* Prepare references to correct column */
468 int &cur_width = (fl == ElementFloat::Left) ? left_width : right_width;
469 int &cur_y = (fl == ElementFloat::Left) ? left_y : right_y;
470 std::vector<size_t> &cur_floats = (fl == ElementFloat::Left) ? left_floats : right_floats;
471 /* Position element */
472 cur_width = std::max(cur_width, this->GetPageElementFloatWidth(*pe));
473 LayoutCacheElement ce{ pe, {} };
474 ce.bounds.left = (fl == ElementFloat::Left) ? 0 : (max_width - cur_width);
475 ce.bounds.right = (fl == ElementFloat::Left) ? cur_width : max_width;
476 ce.bounds.top = cur_y;
478 ce.bounds.bottom = cur_y;
479 cur_floats.push_back(this->layout_cache.size());
480 this->layout_cache.push_back(ce);
482 /* Update floats in column to all have the same width */
483 for (size_t index : cur_floats) {
484 LayoutCacheElement &ce = this->layout_cache[index];
485 ce.bounds.left = (fl == ElementFloat::Left) ? 0 : (max_width - cur_width);
486 ce.bounds.right = (fl == ElementFloat::Left) ? cur_width : max_width;
487 }
488 }
489 }
490 }
491
497 {
499
500 /* The largest bottom coordinate of any element is the height of the content */
501 int32_t max_y = std::accumulate(this->layout_cache.begin(), this->layout_cache.end(), 0, [](int32_t max_y, const LayoutCacheElement &ce) -> int32_t { return std::max<int32_t>(max_y, ce.bounds.bottom); });
502
503 return max_y;
504 }
505
517 void DrawActionElement(int &y_offset, int width, int line_height, SpriteID action_sprite, StringID string_id = STR_JUST_RAW_STRING) const
518 {
520 uint element_height = std::max(sprite_dim.height, (uint)line_height);
521
522 uint sprite_top = y_offset + (element_height - sprite_dim.height) / 2;
523 uint text_top = y_offset + (element_height - line_height) / 2;
524
525 DrawSprite(action_sprite, PAL_NONE, 0, sprite_top);
526 DrawString(sprite_dim.width + WidgetDimensions::scaled.frametext.left, width, text_top, string_id, TC_BLACK);
527
528 y_offset += element_height;
529 }
530
536 {
537 switch (pe.type) {
538 case SPET_TEXT:
539 /* Do nothing. */
540 break;
541
542 case SPET_LOCATION:
543 if (_ctrl_pressed) {
545 } else {
547 }
548 break;
549
550 case SPET_GOAL:
552 break;
553
554 case SPET_BUTTON_PUSH:
555 if (this->active_button_id != INVALID_STORY_PAGE_ELEMENT) ResetObjectToPlace();
556 this->active_button_id = pe.index;
557 this->SetTimeout();
559
561 break;
562
563 case SPET_BUTTON_TILE:
564 if (this->active_button_id == pe.index) {
566 this->active_button_id = INVALID_STORY_PAGE_ELEMENT;
567 } else {
568 CursorID cursor = TranslateStoryPageButtonCursor(StoryPageButtonData{ pe.referenced_id }.GetCursor());
569 SetObjectToPlaceWnd(cursor, PAL_NONE, HT_RECT, this);
570 this->active_button_id = pe.index;
571 }
573 break;
574
576 if (this->active_button_id == pe.index) {
578 this->active_button_id = INVALID_STORY_PAGE_ELEMENT;
579 } else {
580 CursorID cursor = TranslateStoryPageButtonCursor(StoryPageButtonData{ pe.referenced_id }.GetCursor());
581 SetObjectToPlaceWnd(cursor, PAL_NONE, HT_VEHICLE, this);
582 this->active_button_id = pe.index;
583 }
585 break;
586
587 default:
588 NOT_REACHED();
589 }
590 }
591
592public:
594 {
595 this->CreateNestedTree();
596 this->vscroll = this->GetScrollbar(WID_SB_SCROLLBAR);
598
599 /* Initialize page sort. */
600 this->story_pages.SetSortFuncs(StoryBookWindow::page_sorter_funcs);
601 this->story_pages.ForceRebuild();
602 this->BuildStoryPageList();
603 this->story_page_elements.SetSortFuncs(StoryBookWindow::page_element_sorter_funcs);
604 /* story_page_elements will get built by SetSelectedPage */
605
606 this->FinishInitNested(window_number);
607 this->owner = (Owner)this->window_number;
608
609 /* Initialize selected vars. */
610 this->selected_generic_title.clear();
611 this->selected_page_id = INVALID_STORY_PAGE;
612
613 this->active_button_id = INVALID_STORY_PAGE_ELEMENT;
614
615 this->OnInvalidateData(-1);
616 }
617
622 {
623 this->SetWidgetDisabledState(WID_SB_PREV_PAGE, story_pages.empty() || this->IsFirstPageSelected());
624 this->SetWidgetDisabledState(WID_SB_NEXT_PAGE, story_pages.empty() || this->IsLastPageSelected());
627 }
628
634 {
635 if (this->selected_page_id != page_index) {
636 if (this->active_button_id) ResetObjectToPlace();
637 this->active_button_id = INVALID_STORY_PAGE_ELEMENT;
638 this->selected_page_id = page_index;
639 this->RefreshSelectedPage();
641 }
642 }
643
644 void SetStringParameters(WidgetID widget) const override
645 {
646 switch (widget) {
647 case WID_SB_SEL_PAGE: {
648 StoryPage *page = this->GetSelPage();
649 SetDParamStr(0, page != nullptr && !page->title.empty() ? page->title : this->selected_generic_title);
650 break;
651 }
652 case WID_SB_CAPTION:
653 if (this->window_number == INVALID_COMPANY) {
655 } else {
657 SetDParam(1, this->window_number);
658 }
659 break;
660 }
661 }
662
663 void OnPaint() override
664 {
665 /* Detect if content has changed height. This can happen if a
666 * multi-line text contains eg. {COMPANY} and that company is
667 * renamed.
668 */
669 if (this->vscroll->GetCount() != this->GetContentHeight()) {
670 this->vscroll->SetCount(this->GetContentHeight());
673 }
674
675 this->DrawWidgets();
676 }
677
678 void DrawWidget(const Rect &r, WidgetID widget) const override
679 {
680 if (widget != WID_SB_PAGE_PANEL) return;
681
682 StoryPage *page = this->GetSelPage();
683 if (page == nullptr) return;
684
685 Rect fr = r.Shrink(WidgetDimensions::scaled.frametext);
686
687 /* Set up a clipping region for the panel. */
689 if (!FillDrawPixelInfo(&tmp_dpi, fr)) return;
690
692
693 /* Draw content (now coordinates given to Draw** are local to the new clipping region). */
694 fr = fr.Translate(-fr.left, -fr.top);
695 int line_height = GetCharacterHeight(FS_NORMAL);
696 const int scrollpos = this->vscroll->GetPosition();
697 int y_offset = -scrollpos;
698
699 /* Date */
700 if (page->date != CalendarTime::INVALID_DATE) {
701 SetDParam(0, page->date);
702 DrawString(0, fr.right, y_offset, STR_JUST_DATE_LONG, TC_BLACK);
703 }
704 y_offset += line_height;
705
706 /* Title */
707 SetDParamStr(0, !page->title.empty() ? page->title : this->selected_generic_title);
708 y_offset = DrawStringMultiLine(0, fr.right, y_offset, fr.bottom, STR_STORY_BOOK_TITLE, TC_BLACK, SA_TOP | SA_HOR_CENTER);
709
710 /* Page elements */
712 for (const LayoutCacheElement &ce : this->layout_cache) {
713 y_offset = ce.bounds.top - scrollpos;
714 switch (ce.pe->type) {
715 case SPET_TEXT:
716 SetDParamStr(0, ce.pe->text);
717 y_offset = DrawStringMultiLine(ce.bounds.left, ce.bounds.right, ce.bounds.top - scrollpos, ce.bounds.bottom - scrollpos, STR_JUST_RAW_STRING, TC_BLACK, SA_TOP | SA_LEFT);
718 break;
719
720 case SPET_GOAL: {
721 Goal *g = Goal::Get((GoalID) ce.pe->referenced_id);
723 if (g != nullptr) SetDParamStr(0, g->text);
724 DrawActionElement(y_offset, ce.bounds.right - ce.bounds.left, line_height, GetPageElementSprite(*ce.pe), string_id);
725 break;
726 }
727
728 case SPET_LOCATION:
729 SetDParamStr(0, ce.pe->text);
730 DrawActionElement(y_offset, ce.bounds.right - ce.bounds.left, line_height, GetPageElementSprite(*ce.pe));
731 break;
732
733 case SPET_BUTTON_PUSH:
734 case SPET_BUTTON_TILE:
735 case SPET_BUTTON_VEHICLE: {
737 const FrameFlags frame = this->active_button_id == ce.pe->index ? FR_LOWERED : FR_NONE;
738 const Colours bgcolour = StoryPageButtonData{ ce.pe->referenced_id }.GetColour();
739
740 DrawFrameRect(ce.bounds.left, ce.bounds.top - scrollpos, ce.bounds.right, ce.bounds.bottom - scrollpos - 1, bgcolour, frame);
741
742 SetDParamStr(0, ce.pe->text);
743 DrawString(ce.bounds.left + WidgetDimensions::scaled.bevel.left, ce.bounds.right - WidgetDimensions::scaled.bevel.right, ce.bounds.top + tmargin - scrollpos, STR_JUST_RAW_STRING, TC_WHITE, SA_CENTER);
744 break;
745 }
746
747 default: NOT_REACHED();
748 }
749 }
750 }
751
753 {
754 if (widget != WID_SB_SEL_PAGE && widget != WID_SB_PAGE_PANEL) return;
755
756 Dimension d;
758 d.width = 0;
759
760 switch (widget) {
761 case WID_SB_SEL_PAGE: {
762
763 /* Get max title width. */
764 for (size_t i = 0; i < this->story_pages.size(); i++) {
765 const StoryPage *s = this->story_pages[i];
766
767 if (!s->title.empty()) {
768 SetDParamStr(0, s->title);
769 } else {
770 SetDParamStr(0, this->selected_generic_title);
771 }
773
774 if (title_d.width > d.width) {
775 d.width = title_d.width;
776 }
777 }
778
779 d.width += padding.width;
780 d.height += padding.height;
781 size = maxdim(size, d);
782 break;
783 }
784
785 case WID_SB_PAGE_PANEL: {
786 d.height *= 5;
787 d.height += padding.height + WidgetDimensions::scaled.frametext.Vertical();
788 size = maxdim(size, d);
789 break;
790 }
791 }
792
793 }
794
795 void OnResize() override
796 {
798 this->vscroll->SetCapacityFromWidget(this, WID_SB_PAGE_PANEL, WidgetDimensions::scaled.frametext.Vertical());
799 this->vscroll->SetCount(this->GetContentHeight());
800 }
801
802 void OnClick([[maybe_unused]] Point pt, WidgetID widget, [[maybe_unused]] int click_count) override
803 {
804 switch (widget) {
805 case WID_SB_SEL_PAGE: {
806 DropDownList list = this->BuildDropDownList();
807 if (!list.empty()) {
808 /* Get the index of selected page. */
809 int selected = 0;
810 for (size_t i = 0; i < this->story_pages.size(); i++) {
811 const StoryPage *p = this->story_pages[i];
812 if (p->index == this->selected_page_id) break;
813 selected++;
814 }
815
816 ShowDropDownList(this, std::move(list), selected, widget);
817 }
818 break;
819 }
820
821 case WID_SB_PREV_PAGE:
822 this->SelectPrevPage();
823 break;
824
825 case WID_SB_NEXT_PAGE:
826 this->SelectNextPage();
827 break;
828
829 case WID_SB_PAGE_PANEL: {
832
833 for (const LayoutCacheElement &ce : this->layout_cache) {
834 if (clicked_y >= ce.bounds.top && clicked_y < ce.bounds.bottom && pt.x >= ce.bounds.left && pt.x < ce.bounds.right) {
835 this->OnPageElementClick(*ce.pe);
836 return;
837 }
838 }
839 }
840 }
841 }
842
843 void OnDropdownSelect(WidgetID widget, int index) override
844 {
845 if (widget != WID_SB_SEL_PAGE) return;
846
847 /* index (which is set in BuildDropDownList) is the page id. */
848 this->SetSelectedPage(index);
849 }
850
858 void OnInvalidateData([[maybe_unused]] int data = 0, [[maybe_unused]] bool gui_scope = true) override
859 {
860 if (!gui_scope) return;
861
862 /* If added/removed page, force rebuild. Sort order never change so just a
863 * re-sort is never needed.
864 */
865 if (data == -1) {
866 this->story_pages.ForceRebuild();
867 this->BuildStoryPageList();
868
869 /* Was the last page removed? */
870 if (this->story_pages.empty()) {
871 this->selected_generic_title.clear();
872 }
873
874 /* Verify page selection. */
875 if (!_story_page_pool.IsValidID(this->selected_page_id)) {
876 this->selected_page_id = INVALID_STORY_PAGE;
877 }
878 if (this->selected_page_id == INVALID_STORY_PAGE && !this->story_pages.empty()) {
879 /* No page is selected, but there exist at least one available.
880 * => Select first page.
881 */
882 this->SetSelectedPage(this->story_pages[0]->index);
883 }
884
885 this->SetWidgetDisabledState(WID_SB_SEL_PAGE, this->story_pages.empty());
888 } else if (data >= 0 && this->selected_page_id == data) {
889 this->RefreshSelectedPage();
890 }
891 }
892
893 void OnTimeout() override
894 {
895 this->active_button_id = INVALID_STORY_PAGE_ELEMENT;
897 }
898
899 void OnPlaceObject([[maybe_unused]] Point pt, TileIndex tile) override
900 {
901 const StoryPageElement *const pe = StoryPageElement::GetIfValid(this->active_button_id);
902 if (pe == nullptr || pe->type != SPET_BUTTON_TILE) {
904 this->active_button_id = INVALID_STORY_PAGE_ELEMENT;
906 return;
907 }
908
911 }
912
913 bool OnVehicleSelect(const Vehicle *v) override
914 {
915 const StoryPageElement *const pe = StoryPageElement::GetIfValid(this->active_button_id);
916 if (pe == nullptr || pe->type != SPET_BUTTON_VEHICLE) {
918 this->active_button_id = INVALID_STORY_PAGE_ELEMENT;
920 return false;
921 }
922
923 /* Check that the vehicle matches the requested type */
925 VehicleType wanted_vehtype = data.GetVehicleType();
926 if (wanted_vehtype != VEH_INVALID && wanted_vehtype != v->type) return false;
927
930 return true;
931 }
932
933 void OnPlaceObjectAbort() override
934 {
935 this->active_button_id = INVALID_STORY_PAGE_ELEMENT;
937 }
938};
939
940const std::initializer_list<GUIStoryPageList::SortFunction * const> StoryBookWindow::page_sorter_funcs = {
941 &PageOrderSorter,
942};
943
944const std::initializer_list<GUIStoryPageElementList::SortFunction * const> StoryBookWindow::page_element_sorter_funcs = {
945 &PageElementOrderSorter,
946};
947
948static constexpr NWidgetPart _nested_story_book_widgets[] = {
950 NWidget(WWT_CLOSEBOX, COLOUR_BROWN),
951 NWidget(WWT_CAPTION, COLOUR_BROWN, WID_SB_CAPTION), SetDataTip(STR_JUST_STRING1, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
952 NWidget(WWT_SHADEBOX, COLOUR_BROWN),
953 NWidget(WWT_DEFSIZEBOX, COLOUR_BROWN),
954 NWidget(WWT_STICKYBOX, COLOUR_BROWN),
955 EndContainer(),
959 EndContainer(),
961 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),
962 NWidget(NWID_BUTTON_DROPDOWN, COLOUR_BROWN, WID_SB_SEL_PAGE), SetMinimalSize(93, 12), SetFill(1, 0),
963 SetDataTip(STR_JUST_RAW_STRING, STR_STORY_BOOK_SEL_PAGE_TOOLTIP), SetResize(1, 0),
964 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),
965 NWidget(WWT_RESIZEBOX, COLOUR_BROWN),
966 EndContainer(),
967};
968
969static WindowDesc _story_book_desc(
970 WDP_AUTO, "view_story", 400, 300,
972 0,
973 _nested_story_book_widgets
974);
975
976static WindowDesc _story_book_gs_desc(
977 WDP_CENTER, "view_story_gs", 400, 300,
979 0,
980 _nested_story_book_widgets
981);
982
983static CursorID TranslateStoryPageButtonCursor(StoryPageButtonCursor cursor)
984{
985 switch (cursor) {
986 case SPBC_MOUSE: return SPR_CURSOR_MOUSE;
987 case SPBC_ZZZ: return SPR_CURSOR_ZZZ;
988 case SPBC_BUOY: return SPR_CURSOR_BUOY;
989 case SPBC_QUERY: return SPR_CURSOR_QUERY;
990 case SPBC_HQ: return SPR_CURSOR_HQ;
991 case SPBC_SHIP_DEPOT: return SPR_CURSOR_SHIP_DEPOT;
992 case SPBC_SIGN: return SPR_CURSOR_SIGN;
993 case SPBC_TREE: return SPR_CURSOR_TREE;
994 case SPBC_BUY_LAND: return SPR_CURSOR_BUY_LAND;
995 case SPBC_LEVEL_LAND: return SPR_CURSOR_LEVEL_LAND;
996 case SPBC_TOWN: return SPR_CURSOR_TOWN;
997 case SPBC_INDUSTRY: return SPR_CURSOR_INDUSTRY;
998 case SPBC_ROCKY_AREA: return SPR_CURSOR_ROCKY_AREA;
999 case SPBC_DESERT: return SPR_CURSOR_DESERT;
1000 case SPBC_TRANSMITTER: return SPR_CURSOR_TRANSMITTER;
1001 case SPBC_AIRPORT: return SPR_CURSOR_AIRPORT;
1002 case SPBC_DOCK: return SPR_CURSOR_DOCK;
1003 case SPBC_CANAL: return SPR_CURSOR_CANAL;
1004 case SPBC_LOCK: return SPR_CURSOR_LOCK;
1005 case SPBC_RIVER: return SPR_CURSOR_RIVER;
1006 case SPBC_AQUEDUCT: return SPR_CURSOR_AQUEDUCT;
1007 case SPBC_BRIDGE: return SPR_CURSOR_BRIDGE;
1008 case SPBC_RAIL_STATION: return SPR_CURSOR_RAIL_STATION;
1009 case SPBC_TUNNEL_RAIL: return SPR_CURSOR_TUNNEL_RAIL;
1010 case SPBC_TUNNEL_ELRAIL: return SPR_CURSOR_TUNNEL_ELRAIL;
1011 case SPBC_TUNNEL_MONO: return SPR_CURSOR_TUNNEL_MONO;
1012 case SPBC_TUNNEL_MAGLEV: return SPR_CURSOR_TUNNEL_MAGLEV;
1013 case SPBC_AUTORAIL: return SPR_CURSOR_AUTORAIL;
1014 case SPBC_AUTOELRAIL: return SPR_CURSOR_AUTOELRAIL;
1015 case SPBC_AUTOMONO: return SPR_CURSOR_AUTOMONO;
1016 case SPBC_AUTOMAGLEV: return SPR_CURSOR_AUTOMAGLEV;
1017 case SPBC_WAYPOINT: return SPR_CURSOR_WAYPOINT;
1018 case SPBC_RAIL_DEPOT: return SPR_CURSOR_RAIL_DEPOT;
1019 case SPBC_ELRAIL_DEPOT: return SPR_CURSOR_ELRAIL_DEPOT;
1020 case SPBC_MONO_DEPOT: return SPR_CURSOR_MONO_DEPOT;
1021 case SPBC_MAGLEV_DEPOT: return SPR_CURSOR_MAGLEV_DEPOT;
1022 case SPBC_CONVERT_RAIL: return SPR_CURSOR_CONVERT_RAIL;
1023 case SPBC_CONVERT_ELRAIL: return SPR_CURSOR_CONVERT_ELRAIL;
1024 case SPBC_CONVERT_MONO: return SPR_CURSOR_CONVERT_MONO;
1025 case SPBC_CONVERT_MAGLEV: return SPR_CURSOR_CONVERT_MAGLEV;
1026 case SPBC_AUTOROAD: return SPR_CURSOR_AUTOROAD;
1027 case SPBC_AUTOTRAM: return SPR_CURSOR_AUTOTRAM;
1028 case SPBC_ROAD_DEPOT: return SPR_CURSOR_ROAD_DEPOT;
1029 case SPBC_BUS_STATION: return SPR_CURSOR_BUS_STATION;
1030 case SPBC_TRUCK_STATION: return SPR_CURSOR_TRUCK_STATION;
1031 case SPBC_ROAD_TUNNEL: return SPR_CURSOR_ROAD_TUNNEL;
1032 case SPBC_CLONE_TRAIN: return SPR_CURSOR_CLONE_TRAIN;
1033 case SPBC_CLONE_ROADVEH: return SPR_CURSOR_CLONE_ROADVEH;
1034 case SPBC_CLONE_SHIP: return SPR_CURSOR_CLONE_SHIP;
1035 case SPBC_CLONE_AIRPLANE: return SPR_CURSOR_CLONE_AIRPLANE;
1036 case SPBC_DEMOLISH: return ANIMCURSOR_DEMOLISH;
1037 case SPBC_LOWERLAND: return ANIMCURSOR_LOWERLAND;
1038 case SPBC_RAISELAND: return ANIMCURSOR_RAISELAND;
1039 case SPBC_PICKSTATION: return ANIMCURSOR_PICKSTATION;
1040 case SPBC_BUILDSIGNALS: return ANIMCURSOR_BUILDSIGNALS;
1041 default: return SPR_CURSOR_QUERY;
1042 }
1043}
1044
1051void ShowStoryBook(CompanyID company, uint16_t page_id, bool centered)
1052{
1053 if (!Company::IsValidID(company)) company = (CompanyID)INVALID_COMPANY;
1054
1055 StoryBookWindow *w = AllocateWindowDescFront<StoryBookWindow>(centered ? _story_book_gs_desc : _story_book_desc, company, true);
1056 if (page_id != INVALID_STORY_PAGE) w->SetSelectedPage(page_id);
1057}
@ None
Tile is not animated.
List template of 'things' T to sort in a GUI.
void RebuildDone()
Notify the sortlist that the rebuild is done.
bool NeedRebuild() const
Check if a rebuild is needed.
void ForceRebuild()
Force that a rebuild is needed.
bool Sort(Comp compare)
Sort the list.
void SetSortFuncs(std::span< SortFunction *const > n_funcs)
Hand the sort function pointers to the GUIList.
Scrollbar data structure.
void SetCount(size_t num)
Sets the number of elements in the list.
size_type GetScrolledRowFromWidget(int clickpos, const Window *const w, WidgetID widget, int padding=0, int line_height=-1) const
Compute the row of a scrolled widget that a user clicked in.
Definition widget.cpp:2377
void SetCapacityFromWidget(Window *w, WidgetID widget, int padding=0)
Set capacity of visible elements from the size and resize properties of a widget.
Definition widget.cpp:2451
size_type GetCount() const
Gets the number of elements in the list.
void SetStepSize(size_t stepsize)
Set the distance to scroll when using the buttons or the wheel.
size_type GetPosition() const
Gets the position of the first visible element in the list.
static constexpr TimerGame< struct Calendar >::Date INVALID_DATE
Representation of an invalid date.
RectPadding framerect
Standard padding inside many panels.
Definition window_gui.h:42
RectPadding frametext
Padding inside frame with text.
Definition window_gui.h:43
static WidgetDimensions scaled
Widget dimensions scaled for current zoom level.
Definition window_gui.h:28
RectPadding bevel
Bevel thickness, affected by "scaled bevels" game option.
Definition window_gui.h:40
Functions related to commands.
Definition of stuff that is very close to a company, like the company struct itself.
Functions related to companies.
Owner
Enum for all companies/owners.
@ INVALID_COMPANY
An invalid company.
void ShowDropDownList(Window *w, DropDownList &&list, int selected, WidgetID button, uint width, bool instant_close, bool persist)
Show a drop down list.
Definition dropdown.cpp:404
Functions related to the drop down widget.
Types related to the drop down widget.
std::vector< std::unique_ptr< const DropDownListItem > > DropDownList
A drop down list is a collection of drop down list items.
int GetCharacterHeight(FontSize size)
Get height of a character for a given font size.
Definition fontcache.cpp:77
Dimension maxdim(const Dimension &d1, const Dimension &d2)
Compute bounding box of both dimensions.
Geometry functions.
int GetStringHeight(std::string_view str, int maxw, FontSize fontsize)
Calculates height of string (in pixels).
Definition gfx.cpp:704
Dimension GetSpriteSize(SpriteID sprid, Point *offset, ZoomLevel zoom)
Get the size of a sprite.
Definition gfx.cpp:922
Dimension GetStringBoundingBox(std::string_view str, FontSize start_fontsize)
Return the string dimension in pixels.
Definition gfx.cpp:851
int DrawString(int left, int right, int top, std::string_view str, TextColour colour, StringAlignment align, bool underline, FontSize fontsize)
Draw string, possibly truncated to make it fit in its allocated space.
Definition gfx.cpp:657
bool _ctrl_pressed
Is Ctrl pressed?
Definition gfx.cpp:38
void DrawSprite(SpriteID img, PaletteID pal, int x, int y, const SubSprite *sub, ZoomLevel zoom)
Draw a sprite, not in a viewport.
Definition gfx.cpp:988
int DrawStringMultiLine(int left, int right, int top, int bottom, std::string_view str, TextColour colour, StringAlignment align, bool underline, FontSize fontsize)
Draw string, possibly over multiple lines.
Definition gfx.cpp:774
bool FillDrawPixelInfo(DrawPixelInfo *n, int left, int top, int width, int height)
Set up a clipping area for only drawing into a certain area.
Definition gfx.cpp:1548
uint32_t SpriteID
The number of a sprite, without mapping bits and colourtables.
Definition gfx_type.h:18
@ SA_TOP
Top align the text.
Definition gfx_type.h:348
@ SA_LEFT
Left align the text.
Definition gfx_type.h:343
@ SA_HOR_CENTER
Horizontally center the text.
Definition gfx_type.h:344
@ SA_CENTER
Center both horizontally and vertically.
Definition gfx_type.h:353
uint32_t CursorID
The number of the cursor (sprite)
Definition gfx_type.h:20
@ FS_NORMAL
Index of the normal font in the font tables.
Definition gfx_type.h:209
Goal base class.
void ShowGoalsList(CompanyID company)
Open a goal list window.
Definition goal_gui.cpp:316
uint16_t GoalID
ID of a goal.
Definition goal_type.h:37
constexpr NWidgetPart SetFill(uint16_t fill_x, uint16_t fill_y)
Widget part function for setting filling.
constexpr NWidgetPart SetScrollbar(WidgetID index)
Attach a scrollbar to a widget.
constexpr NWidgetPart SetDataTip(uint32_t data, StringID tip)
Widget part function for setting the data and tooltip.
constexpr NWidgetPart SetMinimalSize(int16_t x, int16_t y)
Widget part function for setting the minimal size.
constexpr NWidgetPart NWidget(WidgetType tp, Colours col, WidgetID idx=-1)
Widget part function for starting a new 'real' widget.
constexpr NWidgetPart EndContainer()
Widget part function for denoting the end of a container (horizontal, vertical, WWT_FRAME,...
constexpr NWidgetPart SetResize(int16_t dx, int16_t dy)
Widget part function for setting the resize step.
GUI functions that shouldn't be here.
void ShowExtraViewportWindow(TileIndex tile=INVALID_TILE)
Show a new Extra Viewport window.
A number of safeguards to prevent using unsafe methods.
Base types for having sorted lists in GUIs.
This file contains all sprite-related enums and defines.
static const CursorID ANIMCURSOR_PICKSTATION
716 - 718 - goto-order icon
Definition sprites.h:1511
static const CursorID ANIMCURSOR_BUILDSIGNALS
1292 - 1293 - build signal
Definition sprites.h:1512
static const CursorID SPR_CURSOR_MOUSE
Cursor sprite numbers.
Definition sprites.h:1390
static const CursorID ANIMCURSOR_DEMOLISH
704 - 707 - demolish dynamite
Definition sprites.h:1508
static const CursorID ANIMCURSOR_LOWERLAND
699 - 701 - lower land tool
Definition sprites.h:1509
static const CursorID ANIMCURSOR_RAISELAND
696 - 698 - raise land tool
Definition sprites.h:1510
Definition of base types and functions in a cross-platform compatible way.
StoryPage base class.
StoryPageButtonFlags
Flags available for buttons.
Definition story_base.h:42
@ SPET_LOCATION
An element that references a tile along with a one-line text.
Definition story_base.h:32
@ SPET_GOAL
An element that references a goal.
Definition story_base.h:33
@ SPET_BUTTON_PUSH
A push button that triggers an immediate event.
Definition story_base.h:34
@ SPET_BUTTON_TILE
A button that allows the player to select a tile, and triggers an event with the tile.
Definition story_base.h:35
@ SPET_TEXT
A text element.
Definition story_base.h:31
@ SPET_BUTTON_VEHICLE
A button that allows the player to select a vehicle, and triggers an event wih the vehicle.
Definition story_base.h:36
StoryPageButtonCursor
Mouse cursors usable by story page buttons.
Definition story_base.h:50
Command definitions related to stories.
void ShowStoryBook(CompanyID company, uint16_t page_id, bool centered)
Raise or create the story book window for company, at page page_id.
static const StoryPageElementID INVALID_STORY_PAGE_ELEMENT
Constant representing a non-existing story page element.
Definition story_type.h:21
static const StoryPageID INVALID_STORY_PAGE
Constant representing a non-existing story page.
Definition story_type.h:22
uint16_t StoryPageID
ID of a story page.
Definition story_type.h:16
uint16_t StoryPageElementID
ID of a story page element.
Definition story_type.h:15
Types related to the story widgets.
@ WID_SB_PAGE_PANEL
Page body.
@ WID_SB_SEL_PAGE
Page selector.
@ WID_SB_SCROLLBAR
Scrollbar of the goal list.
@ WID_SB_CAPTION
Caption of the window.
@ WID_SB_PREV_PAGE
Prev button.
@ WID_SB_NEXT_PAGE
Next button.
void SetDParam(size_t n, uint64_t v)
Set a string parameter v at index n in the global string parameter array.
Definition strings.cpp:104
std::string GetString(StringID string)
Resolve the given StringID into a std::string with all the associated DParam lookups and formatting.
Definition strings.cpp:333
void SetDParamStr(size_t n, const char *str)
This function is used to "bind" a C string to a OpenTTD dparam slot.
Definition strings.cpp:371
Functions related to OTTD's strings.
uint32_t StringID
Numeric value that represents a string, independent of the selected language.
Class to backup a specific variable and restore it upon destruction of this object to prevent stack v...
VehicleType type
Type of vehicle.
Dimensions (a width and height) of a rectangle in 2D.
Data about how and where to blit pixels.
Definition gfx_type.h:157
Struct about goals, current and completed.
Definition goal_base.h:21
bool completed
Is the goal completed or not?
Definition goal_base.h:27
std::string text
Text of the goal.
Definition goal_base.h:25
Partial widget specification to allow NWidgets to be written nested.
Coordinates of a point in 2D.
Tindex index
Index of this pool item.
static bool IsValidID(size_t index)
Tests whether given index can be used to get valid (non-nullptr) Titem.
static Pool::IterateWrapper< Titem > Iterate(size_t from=0)
Returns an iterable ensemble of all valid Titem.
static Titem * GetIfValid(size_t index)
Returns Titem with given index.
static Titem * Get(size_t index)
Returns Titem with given index.
Titem * Get(size_t index)
Returns Titem with given index.
bool IsValidID(size_t index)
Tests whether given index can be used to get valid (non-nullptr) Titem.
constexpr uint Horizontal() const
Get total horizontal padding of RectPadding.
constexpr uint Vertical() const
Get total vertical padding of RectPadding.
Specification of a rectangle with absolute coordinates of all edges.
Rect Shrink(int s) const
Copy and shrink Rect by s pixels.
void OnTimeout() override
Called when this window's timeout has been reached.
void BuildStoryPageList()
(Re)Build story page list.
Definition story_gui.cpp:69
void OnPlaceObjectAbort() override
The user cancelled a tile highlight mode that has been set.
void SetStringParameters(WidgetID widget) const override
Initialize string parameters for a widget.
std::string selected_generic_title
If the selected page doesn't have a custom title, this buffer is used to store a generic page title.
Definition story_gui.cpp:61
void OnPageElementClick(const StoryPageElement &pe)
Internal event handler for when a page element is clicked.
void OnDropdownSelect(WidgetID widget, int index) override
A dropdown option associated to this window has been selected.
void OnResize() override
Called after the window got resized.
static bool PageElementOrderSorter(const StoryPageElement *const &a, const StoryPageElement *const &b)
Sort story page elements by order value.
uint GetAvailablePageContentWidth() const
Get the width available for displaying content on the page panel.
void OnPaint() override
The window must be repainted.
bool IsFirstPageSelected()
Check if the selected page is also the first available page.
void DrawWidget(const Rect &r, WidgetID widget) const override
Draw the contents of a nested widget.
DropDownList BuildDropDownList() const
Builds the page selector drop down list.
int GetPageElementFloatWidth(const StoryPageElement &pe) const
Get the width a page element would use if it was floating left or right.
LayoutCache layout_cache
Cached element layout.
Definition story_gui.cpp:56
void UpdatePrevNextDisabledState()
Updates the disabled state of the prev/next buttons.
Scrollbar * vscroll
Scrollbar of the page text.
Definition story_gui.cpp:55
void SelectNextPage()
Selects the next available page after the currently selected page.
void OnInvalidateData(int data=0, bool gui_scope=true) override
Some data on this window has become invalid.
void SelectPrevPage()
Selects the previous available page before the currently selected page.
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.
void RefreshSelectedPage()
Updates the content of selected page.
StoryPageID selected_page_id
Pool index of selected page.
Definition story_gui.cpp:60
bool IsLastPageSelected()
Check if the selected page is also the last available page.
void UpdateWidgetSize(WidgetID widget, Dimension &size, const Dimension &padding, Dimension &fill, Dimension &resize) override
Update size and resize step of a widget in the window.
GUIStoryPageList story_pages
Sorted list of pages.
Definition story_gui.cpp:58
void InvalidateStoryPageElementLayout()
Invalidate the current page layout.
void BuildStoryPageElementList()
(Re)Build story page element list.
Definition story_gui.cpp:93
StoryPage * GetSelPage() const
Get instance of selected page.
static bool PageOrderSorter(const StoryPage *const &a, const StoryPage *const &b)
Sort story pages by order value.
Definition story_gui.cpp:87
void OnClick(Point pt, WidgetID widget, int click_count) override
A click with the left mouse button has been made on the window.
StoryPageElementID active_button_id
Which button element the player is currently using.
Definition story_gui.cpp:63
int32_t GetContentHeight()
Get the total height of the content displayed in this window.
uint GetHeadHeight(int max_width) const
Counts how many pixels of height that are used by Date and Title (excluding marginal after Title,...
uint GetPageElementHeight(const StoryPageElement &pe, int max_width) const
Get the height in pixels used by a page element.
int GetSelPageNum() const
Get the page number of selected page.
void OnPlaceObject(Point pt, TileIndex tile) override
The user clicked some place on the map when a tile highlight mode has been set.
void SetSelectedPage(uint16_t page_index)
Sets the selected page.
SpriteID GetPageElementSprite(const StoryPageElement &pe) const
Decides which sprite to display for a given page element.
void EnsureStoryPageElementLayout() const
Create the page layout if it is missing.
GUIStoryPageElementList story_page_elements
Sorted list of page elements that belong to the current page.
Definition story_gui.cpp:59
ElementFloat GetPageElementFloat(const StoryPageElement &pe) const
Get the float style of a page element.
Helper to construct packed "id" values for button-type StoryPageElement.
Definition story_base.h:122
Struct about story page elements.
Definition story_base.h:144
uint32_t referenced_id
Id of referenced object (location, goal etc.)
Definition story_base.h:149
std::string text
Static content text of page element.
Definition story_base.h:150
uint32_t 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:145
StoryPageElementType type
Type of page element.
Definition story_base.h:147
Struct about stories, current and completed.
Definition story_base.h:164
uint32_t 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:165
CompanyID company
StoryPage is for a specific company; INVALID_COMPANY if it is global.
Definition story_base.h:167
std::string title
Title of story page.
Definition story_base.h:169
TimerGameCalendar::Date date
Date when the page was created.
Definition story_base.h:166
Vehicle data structure.
High level window description.
Definition window_gui.h:159
Data structure for an opened window.
Definition window_gui.h:273
void FinishInitNested(WindowNumber window_number=0)
Perform the second part of the initialization of a nested widget tree.
Definition window.cpp:1733
void DrawWidgets() const
Paint all widgets of a window.
Definition widget.cpp:732
void SetWidgetDirty(WidgetID widget_index) const
Invalidate a widget, i.e.
Definition window.cpp:551
ResizeInfo resize
Resize information.
Definition window_gui.h:314
void CreateNestedTree()
Perform the first part of the initialization of a nested widget tree.
Definition window.cpp:1723
Owner owner
The owner of the content shown in this window. Company colour is acquired from this variable.
Definition window_gui.h:316
void SetTimeout()
Set the timeout flag of the window and initiate the timer.
Definition window_gui.h:361
const NWID * GetWidget(WidgetID widnum) const
Get the nested widget with number widnum from the nested widget tree.
Definition window_gui.h:977
WindowFlags flags
Window flags.
Definition window_gui.h:300
const Scrollbar * GetScrollbar(WidgetID widnum) const
Return the Scrollbar to a widget index.
Definition window.cpp:314
void SetWidgetDisabledState(WidgetID widget_index, bool disab_stat)
Sets the enabled/disabled status of a widget.
Definition window_gui.h:387
int height
Height of the window (number of pixels down in y direction)
Definition window_gui.h:312
int width
width of the window (number of pixels to the right in x direction)
Definition window_gui.h:311
WindowNumber window_number
Window number within the window class.
Definition window_gui.h:302
Functions related to tile highlights.
void ResetObjectToPlace()
Reset the cursor and mouse mode handling back to default (normal cursor, only clicking in windows).
void SetObjectToPlaceWnd(CursorID icon, PaletteID pal, HighLightStyle mode, Window *w)
Change the cursor and mouse click/drag handling to a mode for performing special operations like tile...
@ HT_RECT
rectangle (stations, depots, ...)
@ HT_VEHICLE
vehicle is accepted as target as well (bitmask)
Base class for all vehicles.
VehicleType
Available vehicle types.
@ VEH_INVALID
Non-existing type of vehicle.
bool ScrollMainWindowToTile(TileIndex tile, bool instant)
Scrolls the viewport of the main window to a given location.
Functions related to (drawing on) viewports.
void DrawFrameRect(int left, int top, int right, int bottom, Colours colour, FrameFlags flags)
Draw frame rectangle.
Definition widget.cpp:283
@ NWID_BUTTON_DROPDOWN
Button with a drop-down.
Definition widget_type.h:83
@ NWID_HORIZONTAL
Horizontal container.
Definition widget_type.h:75
@ WWT_TEXTBTN
(Toggle) Button with text
Definition widget_type.h:55
@ WWT_PANEL
Simple depressed panel.
Definition widget_type.h:50
@ WWT_STICKYBOX
Sticky box (at top-right of a window, after WWT_DEFSIZEBOX)
Definition widget_type.h:66
@ WWT_SHADEBOX
Shade box (at top-right of a window, between WWT_DEBUGBOX and WWT_DEFSIZEBOX)
Definition widget_type.h:64
@ WWT_CAPTION
Window caption (window title between closebox and stickybox)
Definition widget_type.h:61
@ NWID_VSCROLLBAR
Vertical scrollbar.
Definition widget_type.h:85
@ WWT_CLOSEBOX
Close box (at top-left of a window)
Definition widget_type.h:69
@ WWT_RESIZEBOX
Resize box (normally at bottom-right of a window)
Definition widget_type.h:68
@ WWT_DEFSIZEBOX
Default window size box (at top-right of a window, between WWT_SHADEBOX and WWT_STICKYBOX)
Definition widget_type.h:65
Window functions not directly related to making/drawing windows.
Functions, definitions and such used only by the GUI.
FrameFlags
Flags to describe the look of the frame.
Definition window_gui.h:24
@ FR_LOWERED
If set the frame is lowered and the background colour brighter (ie. buttons when pressed)
Definition window_gui.h:28
@ WDP_CENTER
Center the window.
Definition window_gui.h:148
@ WDP_AUTO
Find a place automatically.
Definition window_gui.h:147
int WidgetID
Widget ID.
Definition window_type.h:18
int32_t WindowNumber
Number to differentiate different windows of the same class.
@ WC_NONE
No window, redirects to WC_MAIN_WINDOW.
Definition window_type.h:45
@ WC_STORY_BOOK
Story book; Window numbers: