Merge remote-tracking branch 'upstream/master'
This commit is contained in:
+56
-60
@@ -10,7 +10,6 @@
|
||||
#include "stdafx.h"
|
||||
#include "window_gui.h"
|
||||
#include "strings_func.h"
|
||||
#include "date_func.h"
|
||||
#include "gui.h"
|
||||
#include "story_base.h"
|
||||
#include "core/geometry_func.hpp"
|
||||
@@ -32,8 +31,6 @@
|
||||
#include "table/strings.h"
|
||||
#include "table/sprites.h"
|
||||
|
||||
#include <numeric>
|
||||
|
||||
#include "citymania/cm_hotkeys.hpp"
|
||||
|
||||
#include "safeguards.h"
|
||||
@@ -63,7 +60,7 @@ protected:
|
||||
GUIStoryPageList story_pages; ///< Sorted list of pages.
|
||||
GUIStoryPageElementList story_page_elements; ///< Sorted list of page elements that belong to the current page.
|
||||
StoryPageID selected_page_id; ///< Pool index of selected page.
|
||||
char selected_generic_title[255]; ///< If the selected page doesn't have a custom title, this buffer is used to store a generic page title.
|
||||
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.
|
||||
|
||||
StoryPageElementID active_button_id; ///< Which button element the player is currently using
|
||||
|
||||
@@ -191,9 +188,9 @@ protected:
|
||||
{
|
||||
/* Generate generic title if selected page have no custom title. */
|
||||
StoryPage *page = this->GetSelPage();
|
||||
if (page != nullptr && page->title == nullptr) {
|
||||
if (page != nullptr && page->title.empty()) {
|
||||
SetDParam(0, GetSelPageNum() + 1);
|
||||
GetString(selected_generic_title, STR_STORY_BOOK_GENERIC_PAGE_ITEM, lastof(selected_generic_title));
|
||||
selected_generic_title = GetString(STR_STORY_BOOK_GENERIC_PAGE_ITEM);
|
||||
}
|
||||
|
||||
this->story_page_elements.ForceRebuild();
|
||||
@@ -254,21 +251,16 @@ protected:
|
||||
DropDownList BuildDropDownList() const
|
||||
{
|
||||
DropDownList list;
|
||||
uint16 page_num = 1;
|
||||
uint16_t page_num = 1;
|
||||
for (const StoryPage *p : this->story_pages) {
|
||||
bool current_page = p->index == this->selected_page_id;
|
||||
DropDownListStringItem *item = nullptr;
|
||||
if (p->title != nullptr) {
|
||||
item = new DropDownListCharStringItem(p->title, p->index, current_page);
|
||||
if (!p->title.empty()) {
|
||||
list.push_back(std::make_unique<DropDownListStringItem>(p->title, p->index, current_page));
|
||||
} else {
|
||||
/* No custom title => use a generic page title with page number. */
|
||||
DropDownListParamStringItem *str_item =
|
||||
new DropDownListParamStringItem(STR_STORY_BOOK_GENERIC_PAGE_ITEM, p->index, current_page);
|
||||
str_item->SetParam(0, page_num);
|
||||
item = str_item;
|
||||
SetDParam(0, page_num);
|
||||
list.push_back(std::make_unique<DropDownListStringItem>(STR_STORY_BOOK_GENERIC_PAGE_ITEM, p->index, current_page));
|
||||
}
|
||||
|
||||
list.emplace_back(item);
|
||||
page_num++;
|
||||
}
|
||||
|
||||
@@ -297,8 +289,8 @@ protected:
|
||||
int height = 0;
|
||||
|
||||
/* Title lines */
|
||||
height += FONT_HEIGHT_NORMAL; // Date always use exactly one line.
|
||||
SetDParamStr(0, page->title != nullptr ? page->title : this->selected_generic_title);
|
||||
height += GetCharacterHeight(FS_NORMAL); // Date always use exactly one line.
|
||||
SetDParamStr(0, !page->title.empty() ? page->title : this->selected_generic_title);
|
||||
height += GetStringHeight(STR_STORY_BOOK_TITLE, max_width);
|
||||
|
||||
return height;
|
||||
@@ -336,7 +328,7 @@ protected:
|
||||
switch (pe.type) {
|
||||
case SPET_TEXT:
|
||||
SetDParamStr(0, pe.text);
|
||||
return GetStringHeight(STR_BLACK_RAW_STRING, max_width);
|
||||
return GetStringHeight(STR_JUST_RAW_STRING, max_width);
|
||||
|
||||
case SPET_GOAL:
|
||||
case SPET_LOCATION: {
|
||||
@@ -414,7 +406,7 @@ protected:
|
||||
StoryPage *page = this->GetSelPage();
|
||||
if (page == nullptr) return;
|
||||
int max_width = GetAvailablePageContentWidth();
|
||||
int element_dist = FONT_HEIGHT_NORMAL;
|
||||
int element_dist = GetCharacterHeight(FS_NORMAL);
|
||||
|
||||
/* Make space for the header */
|
||||
int main_y = GetHeadHeight(max_width) + element_dist;
|
||||
@@ -435,7 +427,7 @@ protected:
|
||||
|
||||
if (fl == ElementFloat::None) {
|
||||
/* Verify available width */
|
||||
const int min_required_width = 10 * FONT_HEIGHT_NORMAL;
|
||||
const int min_required_width = 10 * GetCharacterHeight(FS_NORMAL);
|
||||
int left_offset = (left_width == 0) ? 0 : (left_width + element_dist);
|
||||
int right_offset = (right_width == 0) ? 0 : (right_width + element_dist);
|
||||
if (left_offset + right_offset + min_required_width >= max_width) {
|
||||
@@ -544,7 +536,7 @@ protected:
|
||||
* Internal event handler for when a page element is clicked.
|
||||
* @param pe The clicked page element.
|
||||
*/
|
||||
void OnPageElementClick(const StoryPageElement& pe)
|
||||
void OnPageElementClick(const StoryPageElement &pe)
|
||||
{
|
||||
switch (pe.type) {
|
||||
case SPET_TEXT:
|
||||
@@ -606,7 +598,7 @@ public:
|
||||
{
|
||||
this->CreateNestedTree();
|
||||
this->vscroll = this->GetScrollbar(WID_SB_SCROLLBAR);
|
||||
this->vscroll->SetStepSize(FONT_HEIGHT_NORMAL);
|
||||
this->vscroll->SetStepSize(GetCharacterHeight(FS_NORMAL));
|
||||
|
||||
/* Initialize page sort. */
|
||||
this->story_pages.SetSortFuncs(StoryBookWindow::page_sorter_funcs);
|
||||
@@ -619,7 +611,7 @@ public:
|
||||
this->owner = (Owner)this->window_number;
|
||||
|
||||
/* Initialize selected vars. */
|
||||
this->selected_generic_title[0] = '\0';
|
||||
this->selected_generic_title.clear();
|
||||
this->selected_page_id = INVALID_STORY_PAGE;
|
||||
|
||||
this->active_button_id = INVALID_STORY_PAGE_ELEMENT;
|
||||
@@ -632,8 +624,8 @@ public:
|
||||
*/
|
||||
void UpdatePrevNextDisabledState()
|
||||
{
|
||||
this->SetWidgetDisabledState(WID_SB_PREV_PAGE, story_pages.size() == 0 || this->IsFirstPageSelected());
|
||||
this->SetWidgetDisabledState(WID_SB_NEXT_PAGE, story_pages.size() == 0 || this->IsLastPageSelected());
|
||||
this->SetWidgetDisabledState(WID_SB_PREV_PAGE, story_pages.empty() || this->IsFirstPageSelected());
|
||||
this->SetWidgetDisabledState(WID_SB_NEXT_PAGE, story_pages.empty() || this->IsLastPageSelected());
|
||||
this->SetWidgetDirty(WID_SB_PREV_PAGE);
|
||||
this->SetWidgetDirty(WID_SB_NEXT_PAGE);
|
||||
}
|
||||
@@ -642,7 +634,7 @@ public:
|
||||
* Sets the selected page.
|
||||
* @param page_index pool index of the page to select.
|
||||
*/
|
||||
void SetSelectedPage(uint16 page_index)
|
||||
void SetSelectedPage(uint16_t page_index)
|
||||
{
|
||||
if (this->selected_page_id != page_index) {
|
||||
if (this->active_button_id) ResetObjectToPlace();
|
||||
@@ -653,12 +645,12 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void SetStringParameters(int widget) const override
|
||||
void SetStringParameters(WidgetID widget) const override
|
||||
{
|
||||
switch (widget) {
|
||||
case WID_SB_SEL_PAGE: {
|
||||
StoryPage *page = this->GetSelPage();
|
||||
SetDParamStr(0, page != nullptr && page->title != nullptr ? page->title : this->selected_generic_title);
|
||||
SetDParamStr(0, page != nullptr && !page->title.empty() ? page->title : this->selected_generic_title);
|
||||
break;
|
||||
}
|
||||
case WID_SB_CAPTION:
|
||||
@@ -687,7 +679,7 @@ public:
|
||||
this->DrawWidgets();
|
||||
}
|
||||
|
||||
void DrawWidget(const Rect &r, int widget) const override
|
||||
void DrawWidget(const Rect &r, WidgetID widget) const override
|
||||
{
|
||||
if (widget != WID_SB_PAGE_PANEL) return;
|
||||
|
||||
@@ -698,26 +690,25 @@ public:
|
||||
|
||||
/* Set up a clipping region for the panel. */
|
||||
DrawPixelInfo tmp_dpi;
|
||||
if (!FillDrawPixelInfo(&tmp_dpi, fr.left, fr.top, fr.Width(), fr.Height())) return;
|
||||
if (!FillDrawPixelInfo(&tmp_dpi, fr)) return;
|
||||
|
||||
DrawPixelInfo *old_dpi = _cur_dpi;
|
||||
_cur_dpi = &tmp_dpi;
|
||||
AutoRestoreBackup dpi_backup(_cur_dpi, &tmp_dpi);
|
||||
|
||||
/* Draw content (now coordinates given to Draw** are local to the new clipping region). */
|
||||
fr = fr.Translate(-fr.left, -fr.top);
|
||||
int line_height = FONT_HEIGHT_NORMAL;
|
||||
int line_height = GetCharacterHeight(FS_NORMAL);
|
||||
const int scrollpos = this->vscroll->GetPosition();
|
||||
int y_offset = -scrollpos;
|
||||
|
||||
/* Date */
|
||||
if (page->date != INVALID_DATE) {
|
||||
if (page->date != CalendarTime::INVALID_DATE) {
|
||||
SetDParam(0, page->date);
|
||||
DrawString(0, fr.right, y_offset, STR_JUST_DATE_LONG, TC_BLACK);
|
||||
}
|
||||
y_offset += line_height;
|
||||
|
||||
/* Title */
|
||||
SetDParamStr(0, page->title != nullptr ? page->title : this->selected_generic_title);
|
||||
SetDParamStr(0, !page->title.empty() ? page->title : this->selected_generic_title);
|
||||
y_offset = DrawStringMultiLine(0, fr.right, y_offset, fr.bottom, STR_STORY_BOOK_TITLE, TC_BLACK, SA_TOP | SA_HOR_CENTER);
|
||||
|
||||
/* Page elements */
|
||||
@@ -760,17 +751,14 @@ public:
|
||||
default: NOT_REACHED();
|
||||
}
|
||||
}
|
||||
|
||||
/* Restore clipping region. */
|
||||
_cur_dpi = old_dpi;
|
||||
}
|
||||
|
||||
void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override
|
||||
void UpdateWidgetSize(WidgetID widget, Dimension *size, [[maybe_unused]] const Dimension &padding, [[maybe_unused]] Dimension *fill, [[maybe_unused]] Dimension *resize) override
|
||||
{
|
||||
if (widget != WID_SB_SEL_PAGE && widget != WID_SB_PAGE_PANEL) return;
|
||||
|
||||
Dimension d;
|
||||
d.height = FONT_HEIGHT_NORMAL;
|
||||
d.height = GetCharacterHeight(FS_NORMAL);
|
||||
d.width = 0;
|
||||
|
||||
switch (widget) {
|
||||
@@ -780,12 +768,12 @@ public:
|
||||
for (size_t i = 0; i < this->story_pages.size(); i++) {
|
||||
const StoryPage *s = this->story_pages[i];
|
||||
|
||||
if (s->title != nullptr) {
|
||||
if (!s->title.empty()) {
|
||||
SetDParamStr(0, s->title);
|
||||
} else {
|
||||
SetDParamStr(0, this->selected_generic_title);
|
||||
}
|
||||
Dimension title_d = GetStringBoundingBox(STR_BLACK_RAW_STRING);
|
||||
Dimension title_d = GetStringBoundingBox(STR_JUST_RAW_STRING);
|
||||
|
||||
if (title_d.width > d.width) {
|
||||
d.width = title_d.width;
|
||||
@@ -815,7 +803,7 @@ public:
|
||||
this->vscroll->SetCount(this->GetContentHeight());
|
||||
}
|
||||
|
||||
void OnClick(Point pt, int widget, int click_count) override
|
||||
void OnClick([[maybe_unused]] Point pt, WidgetID widget, [[maybe_unused]] int click_count) override
|
||||
{
|
||||
switch (widget) {
|
||||
case WID_SB_SEL_PAGE: {
|
||||
@@ -856,7 +844,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void OnDropdownSelect(int widget, int index) override
|
||||
void OnDropdownSelect(WidgetID widget, int index) override
|
||||
{
|
||||
if (widget != WID_SB_SEL_PAGE) return;
|
||||
|
||||
@@ -871,7 +859,7 @@ public:
|
||||
* >= 0 Id of the page that needs to be refreshed. If it is not the current page, nothing happens.
|
||||
* @param gui_scope Whether the call is done from GUI scope. You may not do everything when not in GUI scope. See #InvalidateWindowData() for details.
|
||||
*/
|
||||
void OnInvalidateData(int data = 0, bool gui_scope = true) override
|
||||
void OnInvalidateData([[maybe_unused]] int data = 0, [[maybe_unused]] bool gui_scope = true) override
|
||||
{
|
||||
if (!gui_scope) return;
|
||||
|
||||
@@ -883,22 +871,22 @@ public:
|
||||
this->BuildStoryPageList();
|
||||
|
||||
/* Was the last page removed? */
|
||||
if (this->story_pages.size() == 0) {
|
||||
this->selected_generic_title[0] = '\0';
|
||||
if (this->story_pages.empty()) {
|
||||
this->selected_generic_title.clear();
|
||||
}
|
||||
|
||||
/* Verify page selection. */
|
||||
if (!_story_page_pool.IsValidID(this->selected_page_id)) {
|
||||
this->selected_page_id = INVALID_STORY_PAGE;
|
||||
}
|
||||
if (this->selected_page_id == INVALID_STORY_PAGE && this->story_pages.size() > 0) {
|
||||
if (this->selected_page_id == INVALID_STORY_PAGE && !this->story_pages.empty()) {
|
||||
/* No page is selected, but there exist at least one available.
|
||||
* => Select first page.
|
||||
*/
|
||||
this->SetSelectedPage(this->story_pages[0]->index);
|
||||
}
|
||||
|
||||
this->SetWidgetDisabledState(WID_SB_SEL_PAGE, this->story_pages.size() == 0);
|
||||
this->SetWidgetDisabledState(WID_SB_SEL_PAGE, this->story_pages.empty());
|
||||
this->SetWidgetDirty(WID_SB_SEL_PAGE);
|
||||
this->UpdatePrevNextDisabledState();
|
||||
} else if (data >= 0 && this->selected_page_id == data) {
|
||||
@@ -912,7 +900,7 @@ public:
|
||||
this->SetWidgetDirty(WID_SB_PAGE_PANEL);
|
||||
}
|
||||
|
||||
void OnPlaceObject(Point pt, TileIndex tile) override
|
||||
void OnPlaceObject([[maybe_unused]] Point pt, TileIndex tile) override
|
||||
{
|
||||
const StoryPageElement *const pe = StoryPageElement::GetIfValid(this->active_button_id);
|
||||
if (pe == nullptr || pe->type != SPET_BUTTON_TILE) {
|
||||
@@ -961,32 +949,39 @@ GUIStoryPageElementList::SortFunction * const StoryBookWindow::page_element_sort
|
||||
&PageElementOrderSorter,
|
||||
};
|
||||
|
||||
static const NWidgetPart _nested_story_book_widgets[] = {
|
||||
static constexpr NWidgetPart _nested_story_book_widgets[] = {
|
||||
NWidget(NWID_HORIZONTAL),
|
||||
NWidget(WWT_CLOSEBOX, COLOUR_BROWN),
|
||||
NWidget(WWT_CAPTION, COLOUR_BROWN, WID_SB_CAPTION), SetDataTip(STR_JUST_STRING, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
|
||||
NWidget(WWT_CAPTION, COLOUR_BROWN, WID_SB_CAPTION), SetDataTip(STR_JUST_STRING1, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
|
||||
NWidget(WWT_SHADEBOX, COLOUR_BROWN),
|
||||
NWidget(WWT_DEFSIZEBOX, COLOUR_BROWN),
|
||||
NWidget(WWT_STICKYBOX, COLOUR_BROWN),
|
||||
EndContainer(),
|
||||
NWidget(NWID_HORIZONTAL), SetFill(1, 1),
|
||||
NWidget(NWID_HORIZONTAL),
|
||||
NWidget(WWT_PANEL, COLOUR_BROWN, WID_SB_PAGE_PANEL), SetResize(1, 1), SetScrollbar(WID_SB_SCROLLBAR), EndContainer(),
|
||||
NWidget(NWID_VSCROLLBAR, COLOUR_BROWN, WID_SB_SCROLLBAR),
|
||||
EndContainer(),
|
||||
NWidget(NWID_HORIZONTAL),
|
||||
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),
|
||||
NWidget(NWID_BUTTON_DROPDOWN, COLOUR_BROWN, WID_SB_SEL_PAGE), SetMinimalSize(93, 12), SetFill(1, 0),
|
||||
SetDataTip(STR_BLACK_RAW_STRING, STR_STORY_BOOK_SEL_PAGE_TOOLTIP), SetResize(1, 0),
|
||||
SetDataTip(STR_JUST_RAW_STRING, STR_STORY_BOOK_SEL_PAGE_TOOLTIP), SetResize(1, 0),
|
||||
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),
|
||||
NWidget(WWT_RESIZEBOX, COLOUR_BROWN),
|
||||
EndContainer(),
|
||||
};
|
||||
|
||||
static WindowDesc _story_book_desc(
|
||||
WDP_CENTER, "view_story", 400, 300,
|
||||
static WindowDesc _story_book_desc(__FILE__, __LINE__,
|
||||
WDP_AUTO, "view_story", 400, 300,
|
||||
WC_STORY_BOOK, WC_NONE,
|
||||
0,
|
||||
_nested_story_book_widgets, lengthof(_nested_story_book_widgets)
|
||||
std::begin(_nested_story_book_widgets), std::end(_nested_story_book_widgets)
|
||||
);
|
||||
|
||||
static WindowDesc _story_book_gs_desc(__FILE__, __LINE__,
|
||||
WDP_CENTER, "view_story_gs", 400, 300,
|
||||
WC_STORY_BOOK, WC_NONE,
|
||||
0,
|
||||
std::begin(_nested_story_book_widgets), std::end(_nested_story_book_widgets)
|
||||
);
|
||||
|
||||
static CursorID TranslateStoryPageButtonCursor(StoryPageButtonCursor cursor)
|
||||
@@ -1055,11 +1050,12 @@ static CursorID TranslateStoryPageButtonCursor(StoryPageButtonCursor cursor)
|
||||
* Raise or create the story book window for \a company, at page \a page_id.
|
||||
* @param company 'Owner' of the story book, may be #INVALID_COMPANY.
|
||||
* @param page_id Page to open, may be #INVALID_STORY_PAGE.
|
||||
* @param centered Whether to open the window centered.
|
||||
*/
|
||||
void ShowStoryBook(CompanyID company, uint16 page_id)
|
||||
void ShowStoryBook(CompanyID company, uint16_t page_id, bool centered)
|
||||
{
|
||||
if (!Company::IsValidID(company)) company = (CompanyID)INVALID_COMPANY;
|
||||
|
||||
StoryBookWindow *w = AllocateWindowDescFront<StoryBookWindow>(&_story_book_desc, company, true);
|
||||
StoryBookWindow *w = AllocateWindowDescFront<StoryBookWindow>(centered ? &_story_book_gs_desc : &_story_book_desc, company, true);
|
||||
if (page_id != INVALID_STORY_PAGE) w->SetSelectedPage(page_id);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user