00001
00002
00003
00004
00005
00006
00007
00008
00009
00012 #include "stdafx.h"
00013 #include "window_gui.h"
00014 #include "strings_func.h"
00015 #include "date_func.h"
00016 #include "gui.h"
00017 #include "story_base.h"
00018 #include "core/geometry_func.hpp"
00019 #include "company_func.h"
00020 #include "command_func.h"
00021 #include "widgets/dropdown_type.h"
00022 #include "widgets/dropdown_func.h"
00023 #include "sortlist_type.h"
00024 #include "goal_base.h"
00025 #include "viewport_func.h"
00026 #include "window_func.h"
00027 #include "company_base.h"
00028
00029 #include "widgets/story_widget.h"
00030
00031 #include "table/strings.h"
00032 #include "table/sprites.h"
00033
00034 typedef GUIList<const StoryPage*> GUIStoryPageList;
00035 typedef GUIList<const StoryPageElement*> GUIStoryPageElementList;
00036
00037 struct StoryBookWindow : Window {
00038 protected:
00039 Scrollbar *vscroll;
00040
00041 GUIStoryPageList story_pages;
00042 GUIStoryPageElementList story_page_elements;
00043 StoryPageID selected_page_id;
00044 char selected_generic_title[255];
00045
00046 static GUIStoryPageList::SortFunction * const page_sorter_funcs[];
00047 static GUIStoryPageElementList::SortFunction * const page_element_sorter_funcs[];
00048
00050 void BuildStoryPageList()
00051 {
00052 if (this->story_pages.NeedRebuild()) {
00053 this->story_pages.Clear();
00054
00055 const StoryPage *p;
00056 FOR_ALL_STORY_PAGES(p) {
00057 if (this->IsPageAvailable(p)) {
00058 *this->story_pages.Append() = p;
00059 }
00060 }
00061
00062 this->story_pages.Compact();
00063 this->story_pages.RebuildDone();
00064 }
00065
00066 this->story_pages.Sort();
00067 }
00068
00070 static int CDECL PageOrderSorter(const StoryPage * const *a, const StoryPage * const *b)
00071 {
00072 return (*a)->sort_value - (*b)->sort_value;
00073 }
00074
00076 void BuildStoryPageElementList()
00077 {
00078 if (this->story_page_elements.NeedRebuild()) {
00079 this->story_page_elements.Clear();
00080
00081 const StoryPage *p = GetSelPage();
00082 if (p != NULL) {
00083 const StoryPageElement *pe;
00084 FOR_ALL_STORY_PAGE_ELEMENTS(pe) {
00085 if (pe->page == p->index) {
00086 *this->story_page_elements.Append() = pe;
00087 }
00088 }
00089 }
00090
00091 this->story_page_elements.Compact();
00092 this->story_page_elements.RebuildDone();
00093 }
00094
00095 this->story_page_elements.Sort();
00096 }
00097
00099 static int CDECL PageElementOrderSorter(const StoryPageElement * const *a, const StoryPageElement * const *b)
00100 {
00101 return (*a)->sort_value - (*b)->sort_value;
00102 }
00103
00104
00105
00106
00107
00108
00109 bool IsPageAvailable(const StoryPage *page) const
00110 {
00111 return page->company == INVALID_COMPANY || page->company == this->window_number;
00112 }
00113
00118 StoryPage *GetSelPage() const
00119 {
00120 if (!_story_page_pool.IsValidID(selected_page_id)) return NULL;
00121 return _story_page_pool.Get(selected_page_id);
00122 }
00123
00128 int GetSelPageNum() const
00129 {
00130 int page_number = 0;
00131 for (const StoryPage *const*iter = this->story_pages.Begin(); iter != this->story_pages.End(); iter++) {
00132 const StoryPage *p = *iter;
00133 if (p->index == this->selected_page_id) {
00134 return page_number;
00135 }
00136 page_number++;
00137 }
00138 return -1;
00139 }
00140
00144 bool IsFirstPageSelected()
00145 {
00146
00147 if (!_story_page_pool.IsValidID(this->selected_page_id)) return false;
00148
00149 return (*this->story_pages.Begin())->index == this->selected_page_id;
00150 }
00151
00155 bool IsLastPageSelected()
00156 {
00157
00158 if (!_story_page_pool.IsValidID(this->selected_page_id)) return false;
00159
00160 if (this->story_pages.Length() <= 1) return true;
00161 const StoryPage *last = *(this->story_pages.End() - 1);
00162 return last->index == this->selected_page_id;
00163 }
00164
00168 void RefreshSelectedPage()
00169 {
00170
00171 StoryPage *page = this->GetSelPage();
00172 if (page != NULL && page->title == NULL) {
00173 SetDParam(0, GetSelPageNum() + 1);
00174 GetString(selected_generic_title, STR_STORY_BOOK_GENERIC_PAGE_ITEM, lastof(selected_generic_title));
00175 }
00176
00177 this->story_page_elements.ForceRebuild();
00178 this->BuildStoryPageElementList();
00179
00180 this->vscroll->SetCount(this->GetContentHeight());
00181 this->SetWidgetDirty(WID_SB_SCROLLBAR);
00182 this->SetWidgetDirty(WID_SB_SEL_PAGE);
00183 this->SetWidgetDirty(WID_SB_PAGE_PANEL);
00184 }
00185
00189 void SelectPrevPage()
00190 {
00191 if (!_story_page_pool.IsValidID(this->selected_page_id)) return;
00192
00193
00194 const StoryPage *last_available;
00195 last_available = NULL;
00196 for (const StoryPage *const*iter = this->story_pages.Begin(); iter != this->story_pages.End(); iter++) {
00197 const StoryPage *p = *iter;
00198 if (p->index == this->selected_page_id) {
00199 if (last_available == NULL) return;
00200 this->SetSelectedPage(last_available->index);
00201 return;
00202 }
00203 last_available = p;
00204 }
00205 }
00206
00210 void SelectNextPage()
00211 {
00212 if (!_story_page_pool.IsValidID(this->selected_page_id)) return;
00213
00214
00215 for (const StoryPage *const*iter = this->story_pages.Begin(); iter != this->story_pages.End(); iter++) {
00216 const StoryPage *p = *iter;
00217 if (p->index == this->selected_page_id) {
00218
00219 iter++;
00220 if (iter != this->story_pages.End()) {
00221 this->SetSelectedPage((*iter)->index);
00222 }
00223 return;
00224 }
00225 }
00226 }
00227
00231 DropDownList *BuildDropDownList() const
00232 {
00233 DropDownList *list = new DropDownList();
00234 uint16 page_num = 1;
00235 for (const StoryPage *const*iter = this->story_pages.Begin(); iter != this->story_pages.End(); iter++) {
00236 const StoryPage *p = *iter;
00237 bool current_page = p->index == this->selected_page_id;
00238 DropDownListStringItem *item = NULL;
00239 if (p->title != NULL) {
00240 item = new DropDownListCharStringItem(p->title, p->index, current_page);
00241 } else {
00242
00243 DropDownListParamStringItem *str_item =
00244 new DropDownListParamStringItem(STR_STORY_BOOK_GENERIC_PAGE_ITEM, p->index, current_page);
00245 str_item->SetParam(0, page_num);
00246 item = str_item;
00247 }
00248
00249 *list->Append() = item;
00250 page_num++;
00251 }
00252
00253
00254 if (list->Length() == 0) {
00255 delete list;
00256 list = NULL;
00257 }
00258
00259 return list;
00260 }
00261
00265 uint GetAvailablePageContentWidth()
00266 {
00267 return this->GetWidget<NWidgetCore>(WID_SB_PAGE_PANEL)->current_x - WD_FRAMETEXT_LEFT - WD_FRAMERECT_RIGHT;
00268 }
00269
00277 uint GetHeadHeight(int max_width) const
00278 {
00279 StoryPage *page = this->GetSelPage();
00280 if (page == NULL) return 0;
00281 int height = 0;
00282
00283
00284 height += FONT_HEIGHT_NORMAL;
00285 SetDParamStr(0, page->title != NULL ? page->title : this->selected_generic_title);
00286 height += GetStringHeight(STR_STORY_BOOK_TITLE, max_width);
00287
00288 return height;
00289 }
00290
00297 SpriteID GetPageElementSprite(const StoryPageElement &pe) const
00298 {
00299 switch (pe.type) {
00300 case SPET_GOAL: {
00301 Goal *g = Goal::Get((GoalID) pe.referenced_id);
00302 if (g == NULL) return SPR_IMG_GOAL_BROKEN_REF;
00303 return g->completed ? SPR_IMG_GOAL_COMPLETED : SPR_IMG_GOAL;
00304 }
00305 case SPET_LOCATION:
00306 return SPR_IMG_VIEW_LOCATION;
00307 default:
00308 NOT_REACHED();
00309 }
00310 }
00311
00318 uint GetPageElementHeight(const StoryPageElement &pe, int max_width)
00319 {
00320 switch (pe.type) {
00321 case SPET_TEXT:
00322 SetDParamStr(0, pe.text);
00323 return GetStringHeight(STR_BLACK_RAW_STRING, max_width);
00324 break;
00325
00326 case SPET_GOAL:
00327 case SPET_LOCATION: {
00328 Dimension sprite_dim = GetSpriteSize(GetPageElementSprite(pe));
00329 return sprite_dim.height;
00330 break;
00331 }
00332 default:
00333 NOT_REACHED();
00334 }
00335 return 0;
00336 }
00337
00343 uint GetContentHeight()
00344 {
00345 StoryPage *page = this->GetSelPage();
00346 if (page == NULL) return 0;
00347 int max_width = GetAvailablePageContentWidth();
00348 uint element_vertical_dist = FONT_HEIGHT_NORMAL;
00349
00350
00351 uint height = GetHeadHeight(max_width);
00352
00353
00354 for (const StoryPageElement **iter = this->story_page_elements.Begin(); iter != this->story_page_elements.End(); iter++) {
00355 const StoryPageElement *pe = *iter;
00356 height += element_vertical_dist;
00357 height += GetPageElementHeight(*pe, max_width);
00358 }
00359
00360 return height;
00361 }
00362
00374 void DrawActionElement(int &y_offset, int width, int line_height, SpriteID action_sprite, StringID string_id = STR_JUST_RAW_STRING) const
00375 {
00376 Dimension sprite_dim = GetSpriteSize(action_sprite);
00377 uint element_height = max(sprite_dim.height, (uint)line_height);
00378
00379 uint sprite_top = y_offset + (element_height - sprite_dim.height) / 2;
00380 uint text_top = y_offset + (element_height - line_height) / 2;
00381
00382 DrawSprite(action_sprite, PAL_NONE, 0, sprite_top);
00383 DrawString(sprite_dim.width + WD_FRAMETEXT_LEFT, width, text_top, string_id, TC_BLACK);
00384
00385 y_offset += element_height;
00386 }
00387
00392 void OnPageElementClick(const StoryPageElement& pe)
00393 {
00394 switch (pe.type) {
00395 case SPET_TEXT:
00396
00397 break;
00398
00399 case SPET_LOCATION:
00400 if (_ctrl_pressed) {
00401 ShowExtraViewPortWindow((TileIndex)pe.referenced_id);
00402 } else {
00403 ScrollMainWindowToTile((TileIndex)pe.referenced_id);
00404 }
00405 break;
00406
00407 case SPET_GOAL:
00408 ShowGoalsList((CompanyID)this->window_number);
00409 break;
00410
00411 default:
00412 NOT_REACHED();
00413 }
00414 }
00415
00416 public:
00417 StoryBookWindow(WindowDesc *desc, WindowNumber window_number) : Window(desc)
00418 {
00419 this->CreateNestedTree();
00420 this->vscroll = this->GetScrollbar(WID_SB_SCROLLBAR);
00421 this->vscroll->SetStepSize(FONT_HEIGHT_NORMAL);
00422
00423
00424 this->story_pages.SetSortFuncs(StoryBookWindow::page_sorter_funcs);
00425 this->story_pages.ForceRebuild();
00426 this->BuildStoryPageList();
00427 this->story_page_elements.SetSortFuncs(StoryBookWindow::page_element_sorter_funcs);
00428
00429
00430 this->FinishInitNested(window_number);
00431 this->owner = (Owner)this->window_number;
00432
00433
00434 this->selected_generic_title[0] = '\0';
00435 this->selected_page_id = INVALID_STORY_PAGE;
00436
00437 this->OnInvalidateData(-1);
00438 }
00439
00443 void UpdatePrevNextDisabledState()
00444 {
00445 this->SetWidgetDisabledState(WID_SB_PREV_PAGE, story_pages.Length() == 0 || this->IsFirstPageSelected());
00446 this->SetWidgetDisabledState(WID_SB_NEXT_PAGE, story_pages.Length() == 0 || this->IsLastPageSelected());
00447 this->SetWidgetDirty(WID_SB_PREV_PAGE);
00448 this->SetWidgetDirty(WID_SB_NEXT_PAGE);
00449 }
00450
00455 void SetSelectedPage(uint16 page_index)
00456 {
00457 if (this->selected_page_id != page_index) {
00458 this->selected_page_id = page_index;
00459 this->RefreshSelectedPage();
00460 this->UpdatePrevNextDisabledState();
00461 }
00462 }
00463
00464 virtual void SetStringParameters(int widget) const
00465 {
00466 switch (widget) {
00467 case WID_SB_SEL_PAGE: {
00468 StoryPage *page = this->GetSelPage();
00469 SetDParamStr(0, page != NULL && page->title != NULL ? page->title : this->selected_generic_title);
00470 break;
00471 }
00472 case WID_SB_CAPTION:
00473 if (this->window_number == INVALID_COMPANY) {
00474 SetDParam(0, STR_STORY_BOOK_SPECTATOR_CAPTION);
00475 } else {
00476 SetDParam(0, STR_STORY_BOOK_CAPTION);
00477 SetDParam(1, this->window_number);
00478 }
00479 break;
00480 }
00481 }
00482
00483 virtual void OnPaint()
00484 {
00485
00486
00487
00488
00489 if (this->vscroll->GetCount() != this->GetContentHeight()) {
00490 this->vscroll->SetCount(this->GetContentHeight());
00491 this->SetWidgetDirty(WID_SB_SCROLLBAR);
00492 this->SetWidgetDirty(WID_SB_PAGE_PANEL);
00493 }
00494
00495 this->DrawWidgets();
00496 }
00497
00498 virtual void DrawWidget(const Rect &r, int widget) const
00499 {
00500 if (widget != WID_SB_PAGE_PANEL) return;
00501
00502 StoryPage *page = this->GetSelPage();
00503 if (page == NULL) return;
00504
00505 const int x = r.left + WD_FRAMETEXT_LEFT;
00506 const int y = r.top + WD_FRAMETEXT_TOP;
00507 const int right = r.right - WD_FRAMETEXT_RIGHT;
00508 const int bottom = r.bottom - WD_FRAMETEXT_BOTTOM;
00509
00510
00511 DrawPixelInfo tmp_dpi;
00512 if (!FillDrawPixelInfo(&tmp_dpi, x, y, right - x + 1, bottom - y + 1)) return;
00513
00514 DrawPixelInfo *old_dpi = _cur_dpi;
00515 _cur_dpi = &tmp_dpi;
00516
00517
00518 int line_height = FONT_HEIGHT_NORMAL;
00519 int y_offset = - this->vscroll->GetPosition();
00520
00521
00522 if (page->date != INVALID_DATE) {
00523 SetDParam(0, page->date);
00524 DrawString(0, right - x, y_offset, STR_JUST_DATE_LONG, TC_BLACK);
00525 }
00526 y_offset += line_height;
00527
00528
00529 SetDParamStr(0, page->title != NULL ? page->title : this->selected_generic_title);
00530 y_offset = DrawStringMultiLine(0, right - x, y_offset, bottom - y, STR_STORY_BOOK_TITLE, TC_BLACK, SA_TOP | SA_HOR_CENTER);
00531
00532
00533 for (const StoryPageElement *const*iter = this->story_page_elements.Begin(); iter != this->story_page_elements.End(); iter++) {
00534 const StoryPageElement *const pe = *iter;
00535 y_offset += line_height;
00536
00537 switch (pe->type) {
00538 case SPET_TEXT:
00539 SetDParamStr(0, pe->text);
00540 y_offset = DrawStringMultiLine(0, right - x, y_offset, bottom - y, STR_JUST_RAW_STRING, TC_BLACK, SA_TOP | SA_LEFT);
00541 break;
00542
00543 case SPET_GOAL: {
00544 Goal *g = Goal::Get((GoalID) pe->referenced_id);
00545 StringID string_id = g == NULL ? STR_STORY_BOOK_INVALID_GOAL_REF : STR_JUST_RAW_STRING;
00546 if (g != NULL) SetDParamStr(0, g->text);
00547 DrawActionElement(y_offset, right - x, line_height, GetPageElementSprite(*pe), string_id);
00548 break;
00549 }
00550
00551 case SPET_LOCATION:
00552 SetDParamStr(0, pe->text);
00553 DrawActionElement(y_offset, right - x, line_height, GetPageElementSprite(*pe));
00554 break;
00555
00556 default: NOT_REACHED();
00557 }
00558 }
00559
00560
00561 _cur_dpi = old_dpi;
00562 }
00563
00564 virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
00565 {
00566 if (widget != WID_SB_SEL_PAGE && widget != WID_SB_PAGE_PANEL) return;
00567
00568 Dimension d;
00569 d.height= FONT_HEIGHT_NORMAL;
00570 d.width = 0;
00571
00572 switch(widget) {
00573 case WID_SB_SEL_PAGE: {
00574
00575
00576 for (uint16 i = 0; i < this->story_pages.Length(); i++) {
00577 const StoryPage *s = this->story_pages[i];
00578
00579 if (s->title != NULL) {
00580 SetDParamStr(0, s->title);
00581 } else {
00582 SetDParamStr(0, this->selected_generic_title);
00583 }
00584 Dimension title_d = GetStringBoundingBox(STR_BLACK_RAW_STRING);
00585
00586 if (title_d.width > d.width) {
00587 d.width = title_d.width;
00588 }
00589 }
00590
00591 d.width += padding.width;
00592 d.height += padding.height;
00593 *size = maxdim(*size, d);
00594 break;
00595 }
00596
00597 case WID_SB_PAGE_PANEL: {
00598 d.height *= 5;
00599 d.height += padding.height + WD_FRAMETEXT_TOP + WD_FRAMETEXT_BOTTOM;
00600 *size = maxdim(*size, d);
00601 break;
00602 }
00603 }
00604
00605 }
00606
00607 virtual void OnResize()
00608 {
00609 this->vscroll->SetCapacityFromWidget(this, WID_SB_PAGE_PANEL, WD_FRAMETEXT_TOP + WD_FRAMETEXT_BOTTOM);
00610 this->vscroll->SetCount(this->GetContentHeight());
00611 }
00612
00613 virtual void OnClick(Point pt, int widget, int click_count)
00614 {
00615 switch (widget) {
00616 case WID_SB_SEL_PAGE: {
00617 DropDownList *list = this->BuildDropDownList();
00618 if (list != NULL) {
00619
00620 int selected = 0;
00621 for (uint16 i = 0; i < this->story_pages.Length(); i++) {
00622 const StoryPage *p = this->story_pages[i];
00623 if (p->index == this->selected_page_id) break;
00624 selected++;
00625 }
00626
00627 ShowDropDownList(this, list, selected, widget);
00628 }
00629 break;
00630 }
00631
00632 case WID_SB_PREV_PAGE:
00633 this->SelectPrevPage();
00634 break;
00635
00636 case WID_SB_NEXT_PAGE:
00637 this->SelectNextPage();
00638 break;
00639
00640 case WID_SB_PAGE_PANEL: {
00641 uint clicked_y = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_SB_PAGE_PANEL, WD_FRAMETEXT_TOP);
00642 uint max_width = GetAvailablePageContentWidth();
00643
00644
00645 uint head_height = this->GetHeadHeight(max_width);
00646 if (clicked_y < head_height) return;
00647
00648
00649 uint y = head_height;
00650 uint element_vertical_dist = FONT_HEIGHT_NORMAL;
00651 for (const StoryPageElement *const*iter = this->story_page_elements.Begin(); iter != this->story_page_elements.End(); iter++) {
00652 const StoryPageElement *const pe = *iter;
00653
00654 y += element_vertical_dist;
00655
00656 uint content_height = GetPageElementHeight(*pe, max_width);
00657 if (clicked_y >= y && clicked_y < y + content_height) {
00658 this->OnPageElementClick(*pe);
00659 return;
00660 }
00661
00662 y += content_height;
00663 }
00664 }
00665 }
00666 }
00667
00668 virtual void OnDropdownSelect(int widget, int index)
00669 {
00670 if (widget != WID_SB_SEL_PAGE) return;
00671
00672
00673 this->SetSelectedPage(index);
00674 }
00675
00683 virtual void OnInvalidateData(int data = 0, bool gui_scope = true)
00684 {
00685 if (!gui_scope) return;
00686
00687
00688
00689
00690 if (data == -1) {
00691 this->story_pages.ForceRebuild();
00692 this->BuildStoryPageList();
00693
00694
00695 if (this->story_pages.Length() == 0) {
00696 this->selected_generic_title[0] = '\0';
00697 }
00698
00699
00700 if (!_story_page_pool.IsValidID(this->selected_page_id)) {
00701 this->selected_page_id = INVALID_STORY_PAGE;
00702 }
00703 if (this->selected_page_id == INVALID_STORY_PAGE && this->story_pages.Length() > 0) {
00704
00705
00706
00707 this->SetSelectedPage(this->story_pages[0]->index);
00708 }
00709
00710 this->SetWidgetDisabledState(WID_SB_SEL_PAGE, this->story_pages.Length() == 0);
00711 this->SetWidgetDirty(WID_SB_SEL_PAGE);
00712 this->UpdatePrevNextDisabledState();
00713 } else if (data >= 0 && this->selected_page_id == data) {
00714 this->RefreshSelectedPage();
00715 }
00716 }
00717 };
00718
00719 GUIStoryPageList::SortFunction * const StoryBookWindow::page_sorter_funcs[] = {
00720 &PageOrderSorter,
00721 };
00722
00723 GUIStoryPageElementList::SortFunction * const StoryBookWindow::page_element_sorter_funcs[] = {
00724 &PageElementOrderSorter,
00725 };
00726
00727 static const NWidgetPart _nested_story_book_widgets[] = {
00728 NWidget(NWID_HORIZONTAL),
00729 NWidget(WWT_CLOSEBOX, COLOUR_BROWN),
00730 NWidget(WWT_CAPTION, COLOUR_BROWN, WID_SB_CAPTION), SetDataTip(STR_JUST_STRING, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
00731 NWidget(WWT_SHADEBOX, COLOUR_BROWN),
00732 NWidget(WWT_DEFSIZEBOX, COLOUR_BROWN),
00733 NWidget(WWT_STICKYBOX, COLOUR_BROWN),
00734 EndContainer(),
00735 NWidget(NWID_HORIZONTAL), SetFill(1, 1),
00736 NWidget(NWID_VERTICAL), SetFill(1, 1),
00737 NWidget(WWT_PANEL, COLOUR_BROWN, WID_SB_PAGE_PANEL), SetResize(1, 1), SetScrollbar(WID_SB_SCROLLBAR), EndContainer(),
00738 NWidget(NWID_HORIZONTAL),
00739 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),
00740 NWidget(NWID_BUTTON_DROPDOWN, COLOUR_BROWN, WID_SB_SEL_PAGE), SetMinimalSize(93, 12), SetFill(1, 0),
00741 SetDataTip(STR_BLACK_RAW_STRING, STR_STORY_BOOK_SEL_PAGE_TOOLTIP), SetResize(1, 0),
00742 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),
00743 EndContainer(),
00744 EndContainer(),
00745 NWidget(NWID_VERTICAL), SetFill(0, 1),
00746 NWidget(NWID_VSCROLLBAR, COLOUR_BROWN, WID_SB_SCROLLBAR),
00747 NWidget(WWT_RESIZEBOX, COLOUR_BROWN),
00748 EndContainer(),
00749 EndContainer(),
00750 };
00751
00752 static WindowDesc _story_book_desc(
00753 WDP_CENTER, "view_story", 400, 300,
00754 WC_STORY_BOOK, WC_NONE,
00755 0,
00756 _nested_story_book_widgets, lengthof(_nested_story_book_widgets)
00757 );
00758
00759 void ShowStoryBook(CompanyID company, uint16 page_id)
00760 {
00761 if (!Company::IsValidID(company)) company = (CompanyID)INVALID_COMPANY;
00762
00763 StoryBookWindow *w = AllocateWindowDescFront<StoryBookWindow>(&_story_book_desc, company);
00764 if (page_id != INVALID_STORY_PAGE) {
00765 if (w == NULL) w = (StoryBookWindow *)FindWindowById(WC_STORY_BOOK, company);
00766 w->SetSelectedPage(page_id);
00767 }
00768 }