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 SetDParam(0, page->date);
00523 DrawString(0, right - x, y_offset, STR_JUST_DATE_LONG, TC_BLACK);
00524 y_offset += line_height;
00525
00526
00527 SetDParamStr(0, page->title != NULL ? page->title : this->selected_generic_title);
00528 y_offset = DrawStringMultiLine(0, right - x, y_offset, bottom - y, STR_STORY_BOOK_TITLE, TC_BLACK, SA_TOP | SA_HOR_CENTER);
00529
00530
00531 for (const StoryPageElement *const*iter = this->story_page_elements.Begin(); iter != this->story_page_elements.End(); iter++) {
00532 const StoryPageElement *const pe = *iter;
00533 y_offset += line_height;
00534
00535 switch (pe->type) {
00536 case SPET_TEXT:
00537 SetDParamStr(0, pe->text);
00538 y_offset = DrawStringMultiLine(0, right - x, y_offset, bottom - y, STR_JUST_RAW_STRING, TC_BLACK, SA_TOP | SA_LEFT);
00539 break;
00540
00541 case SPET_GOAL: {
00542 Goal *g = Goal::Get((GoalID) pe->referenced_id);
00543 StringID string_id = g == NULL ? STR_STORY_BOOK_INVALID_GOAL_REF : STR_JUST_RAW_STRING;
00544 if (g != NULL) SetDParamStr(0, g->text);
00545 DrawActionElement(y_offset, right - x, line_height, GetPageElementSprite(*pe), string_id);
00546 break;
00547 }
00548
00549 case SPET_LOCATION:
00550 SetDParamStr(0, pe->text);
00551 DrawActionElement(y_offset, right - x, line_height, GetPageElementSprite(*pe));
00552 break;
00553
00554 default: NOT_REACHED();
00555 }
00556 }
00557
00558
00559 _cur_dpi = old_dpi;
00560 }
00561
00562 virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
00563 {
00564 if (widget != WID_SB_SEL_PAGE && widget != WID_SB_PAGE_PANEL) return;
00565
00566 Dimension d;
00567 d.height= FONT_HEIGHT_NORMAL;
00568 d.width = 0;
00569
00570 switch(widget) {
00571 case WID_SB_SEL_PAGE: {
00572
00573
00574 for (uint16 i = 0; i < this->story_pages.Length(); i++) {
00575 const StoryPage *s = this->story_pages[i];
00576
00577 if (s->title != NULL) {
00578 SetDParamStr(0, s->title);
00579 } else {
00580 SetDParamStr(0, this->selected_generic_title);
00581 }
00582 Dimension title_d = GetStringBoundingBox(STR_BLACK_RAW_STRING);
00583
00584 if (title_d.width > d.width) {
00585 d.width = title_d.width;
00586 }
00587 }
00588
00589 d.width += padding.width;
00590 d.height += padding.height;
00591 *size = maxdim(*size, d);
00592 break;
00593 }
00594
00595 case WID_SB_PAGE_PANEL: {
00596 d.height *= 5;
00597 d.height += padding.height + WD_FRAMETEXT_TOP + WD_FRAMETEXT_BOTTOM;
00598 *size = maxdim(*size, d);
00599 break;
00600 }
00601 }
00602
00603 }
00604
00605 virtual void OnResize()
00606 {
00607 this->vscroll->SetCapacityFromWidget(this, WID_SB_PAGE_PANEL, WD_FRAMETEXT_TOP + WD_FRAMETEXT_BOTTOM);
00608 this->vscroll->SetCount(this->GetContentHeight());
00609 }
00610
00611 virtual void OnClick(Point pt, int widget, int click_count)
00612 {
00613 switch (widget) {
00614 case WID_SB_SEL_PAGE: {
00615 DropDownList *list = this->BuildDropDownList();
00616 if (list != NULL) {
00617
00618 int selected = 0;
00619 for (uint16 i = 0; i < this->story_pages.Length(); i++) {
00620 const StoryPage *p = this->story_pages[i];
00621 if (p->index == this->selected_page_id) break;
00622 selected++;
00623 }
00624
00625 ShowDropDownList(this, list, selected, widget);
00626 }
00627 break;
00628 }
00629
00630 case WID_SB_PREV_PAGE:
00631 this->SelectPrevPage();
00632 break;
00633
00634 case WID_SB_NEXT_PAGE:
00635 this->SelectNextPage();
00636 break;
00637
00638 case WID_SB_PAGE_PANEL: {
00639 uint clicked_y = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_SB_PAGE_PANEL, WD_FRAMETEXT_TOP);
00640 uint max_width = GetAvailablePageContentWidth();
00641
00642
00643 uint head_height = this->GetHeadHeight(max_width);
00644 if (clicked_y < head_height) return;
00645
00646
00647 uint y = head_height;
00648 uint element_vertical_dist = FONT_HEIGHT_NORMAL;
00649 for (const StoryPageElement *const*iter = this->story_page_elements.Begin(); iter != this->story_page_elements.End(); iter++) {
00650 const StoryPageElement *const pe = *iter;
00651
00652 y += element_vertical_dist;
00653
00654 uint content_height = GetPageElementHeight(*pe, max_width);
00655 if (clicked_y >= y && clicked_y < y + content_height) {
00656 this->OnPageElementClick(*pe);
00657 return;
00658 }
00659
00660 y += content_height;
00661 }
00662 }
00663 }
00664 }
00665
00666 virtual void OnDropdownSelect(int widget, int index)
00667 {
00668 if (widget != WID_SB_SEL_PAGE) return;
00669
00670
00671 this->SetSelectedPage(index);
00672 }
00673
00681 virtual void OnInvalidateData(int data = 0, bool gui_scope = true)
00682 {
00683 if (!gui_scope) return;
00684
00685
00686
00687
00688 if (data == -1) {
00689 this->story_pages.ForceRebuild();
00690 this->BuildStoryPageList();
00691
00692
00693 if (this->story_pages.Length() == 0) {
00694 this->selected_generic_title[0] = '\0';
00695 }
00696
00697
00698 if (!_story_page_pool.IsValidID(this->selected_page_id)) {
00699 this->selected_page_id = INVALID_STORY_PAGE;
00700 }
00701 if (this->selected_page_id == INVALID_STORY_PAGE && this->story_pages.Length() > 0) {
00702
00703
00704
00705 this->SetSelectedPage(this->story_pages[0]->index);
00706 }
00707
00708 this->SetWidgetDisabledState(WID_SB_SEL_PAGE, this->story_pages.Length() == 0);
00709 this->SetWidgetDirty(WID_SB_SEL_PAGE);
00710 this->UpdatePrevNextDisabledState();
00711 } else if (data >= 0 && this->selected_page_id == data) {
00712 this->RefreshSelectedPage();
00713 }
00714 }
00715 };
00716
00717 GUIStoryPageList::SortFunction * const StoryBookWindow::page_sorter_funcs[] = {
00718 &PageOrderSorter,
00719 };
00720
00721 GUIStoryPageElementList::SortFunction * const StoryBookWindow::page_element_sorter_funcs[] = {
00722 &PageElementOrderSorter,
00723 };
00724
00725 static const NWidgetPart _nested_story_book_widgets[] = {
00726 NWidget(NWID_HORIZONTAL),
00727 NWidget(WWT_CLOSEBOX, COLOUR_BROWN),
00728 NWidget(WWT_CAPTION, COLOUR_BROWN, WID_SB_CAPTION), SetDataTip(STR_JUST_STRING, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
00729 NWidget(WWT_SHADEBOX, COLOUR_BROWN),
00730 NWidget(WWT_DEFSIZEBOX, COLOUR_BROWN),
00731 NWidget(WWT_STICKYBOX, COLOUR_BROWN),
00732 EndContainer(),
00733 NWidget(NWID_HORIZONTAL), SetFill(1, 1),
00734 NWidget(NWID_VERTICAL), SetFill(1, 1),
00735 NWidget(WWT_PANEL, COLOUR_BROWN, WID_SB_PAGE_PANEL), SetResize(1, 1), SetScrollbar(WID_SB_SCROLLBAR), EndContainer(),
00736 NWidget(NWID_HORIZONTAL),
00737 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),
00738 NWidget(NWID_BUTTON_DROPDOWN, COLOUR_BROWN, WID_SB_SEL_PAGE), SetMinimalSize(93, 12), SetFill(1, 0),
00739 SetDataTip(STR_BLACK_RAW_STRING, STR_STORY_BOOK_SEL_PAGE_TOOLTIP), SetResize(1, 0),
00740 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),
00741 EndContainer(),
00742 EndContainer(),
00743 NWidget(NWID_VERTICAL), SetFill(0, 1),
00744 NWidget(NWID_VSCROLLBAR, COLOUR_BROWN, WID_SB_SCROLLBAR),
00745 NWidget(WWT_RESIZEBOX, COLOUR_BROWN),
00746 EndContainer(),
00747 EndContainer(),
00748 };
00749
00750 static WindowDesc _story_book_desc(
00751 WDP_CENTER, "view_story", 400, 300,
00752 WC_STORY_BOOK, WC_NONE,
00753 0,
00754 _nested_story_book_widgets, lengthof(_nested_story_book_widgets)
00755 );
00756
00757 void ShowStoryBook(CompanyID company, uint16 page_id)
00758 {
00759 if (!Company::IsValidID(company)) company = (CompanyID)INVALID_COMPANY;
00760
00761 StoryBookWindow *w = AllocateWindowDescFront<StoryBookWindow>(&_story_book_desc, company);
00762 if (page_id != INVALID_STORY_PAGE) {
00763 if (w == NULL) w = (StoryBookWindow *)FindWindowById(WC_STORY_BOOK, company);
00764 w->SetSelectedPage(page_id);
00765 }
00766 }