diff options
author | TELK <telk5093@gmail.com> | 2019-07-23 04:27:39 +0900 |
---|---|---|
committer | Charles Pigott <charlespigott@googlemail.com> | 2019-07-22 20:27:39 +0100 |
commit | 196d586849684e62aa9a40093f2a1ce60e1cd53f (patch) | |
tree | 519f846ac8a112571e46127fed937aa5008e5699 /src | |
parent | d71a7c21da27e5f99e48b8ad21b669d078932e35 (diff) | |
download | openttd-196d586849684e62aa9a40093f2a1ce60e1cd53f.tar.xz |
Feature: Town name filtering (#7621)
Diffstat (limited to 'src')
-rw-r--r-- | src/script/api/game/game_window.hpp.sq | 1 | ||||
-rw-r--r-- | src/script/api/script_window.hpp | 1 | ||||
-rw-r--r-- | src/town.h | 6 | ||||
-rw-r--r-- | src/town_gui.cpp | 63 | ||||
-rw-r--r-- | src/widgets/town_widget.h | 1 |
5 files changed, 63 insertions, 9 deletions
diff --git a/src/script/api/game/game_window.hpp.sq b/src/script/api/game/game_window.hpp.sq index da1d30dde..fe665a4ad 100644 --- a/src/script/api/game/game_window.hpp.sq +++ b/src/script/api/game/game_window.hpp.sq @@ -1254,6 +1254,7 @@ void SQGSWindow_Register(Squirrel *engine) SQGSWindow.DefSQConst(engine, ScriptWindow::WID_TE_SWITCH_BAR, "WID_TE_SWITCH_BAR"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_TD_SORT_ORDER, "WID_TD_SORT_ORDER"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_TD_SORT_CRITERIA, "WID_TD_SORT_CRITERIA"); + SQGSWindow.DefSQConst(engine, ScriptWindow::WID_TD_FILTER, "WID_TD_FILTER"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_TD_LIST, "WID_TD_LIST"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_TD_SCROLLBAR, "WID_TD_SCROLLBAR"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_TD_WORLD_POPULATION, "WID_TD_WORLD_POPULATION"); diff --git a/src/script/api/script_window.hpp b/src/script/api/script_window.hpp index 902b19244..3abc091d6 100644 --- a/src/script/api/script_window.hpp +++ b/src/script/api/script_window.hpp @@ -2486,6 +2486,7 @@ public: enum TownDirectoryWidgets { WID_TD_SORT_ORDER = ::WID_TD_SORT_ORDER, ///< Direction of sort dropdown. WID_TD_SORT_CRITERIA = ::WID_TD_SORT_CRITERIA, ///< Criteria of sort dropdown. + WID_TD_FILTER = ::WID_TD_FILTER, ///< Filter of name. WID_TD_LIST = ::WID_TD_LIST, ///< List of towns. WID_TD_SCROLLBAR = ::WID_TD_SCROLLBAR, ///< Scrollbar for the town list. WID_TD_WORLD_POPULATION = ::WID_TD_WORLD_POPULATION, ///< The world's population. diff --git a/src/town.h b/src/town.h index d669ccafb..ce938ea06 100644 --- a/src/town.h +++ b/src/town.h @@ -158,6 +158,12 @@ enum TownRatingCheckType { TOWN_RATING_CHECK_TYPE_COUNT, ///< Number of town checking action types. }; +/** Special values for town list window for the data parameter of #InvalidateWindowData. */ +enum TownDirectoryInvalidateWindowData { + TDIWD_FORCE_REBUILD, + TDIWD_FILTER_CHANGES, ///< The filename filter has changed (via the editbox) +}; + /** * This enum is used in conjunction with town->flags. * IT simply states what bit is used for. diff --git a/src/town_gui.cpp b/src/town_gui.cpp index 5cb589d31..f9670e84e 100644 --- a/src/town_gui.cpp +++ b/src/town_gui.cpp @@ -31,6 +31,7 @@ #include "townname_func.h" #include "core/geometry_func.hpp" #include "genworld.h" +#include "stringfilter_type.h" #include "widgets/dropdown_func.h" #include "widgets/town_widget.h" @@ -636,7 +637,7 @@ static const NWidgetPart _nested_town_directory_widgets[] = { NWidget(NWID_HORIZONTAL), NWidget(WWT_TEXTBTN, COLOUR_BROWN, WID_TD_SORT_ORDER), SetDataTip(STR_BUTTON_SORT_BY, STR_TOOLTIP_SORT_ORDER), NWidget(WWT_DROPDOWN, COLOUR_BROWN, WID_TD_SORT_CRITERIA), SetDataTip(STR_JUST_STRING, STR_TOOLTIP_SORT_CRITERIA), - NWidget(WWT_PANEL, COLOUR_BROWN), SetResize(1, 0), EndContainer(), + NWidget(WWT_EDITBOX, COLOUR_BROWN, WID_TD_FILTER), SetFill(35, 12), SetDataTip(STR_LIST_FILTER_OSKTITLE, STR_LIST_FILTER_TOOLTIP), EndContainer(), NWidget(WWT_PANEL, COLOUR_BROWN, WID_TD_LIST), SetMinimalSize(196, 0), SetDataTip(0x0, STR_TOWN_DIRECTORY_LIST_TOOLTIP), SetFill(1, 0), SetResize(0, 10), SetScrollbar(WID_TD_SCROLLBAR), EndContainer(), @@ -662,6 +663,9 @@ private: static const StringID sorter_names[]; static GUITownList::SortFunction * const sorter_funcs[]; + StringFilter string_filter; ///< Filter for towns + QueryString townname_editbox; ///< Filter editbox + GUITownList towns; Scrollbar *vscroll; @@ -689,8 +693,8 @@ private: /** Sort by town name */ static bool TownNameSorter(const Town * const &a, const Town * const &b) { - static char buf_cache[64]; - char buf[64]; + static char buf_cache[MAX_LENGTH_TOWN_NAME_CHARS * MAX_CHAR_LENGTH]; + char buf[MAX_LENGTH_TOWN_NAME_CHARS * MAX_CHAR_LENGTH]; SetDParam(0, a->index); GetString(buf, STR_TOWN_NAME, lastof(buf)); @@ -739,7 +743,7 @@ private: } public: - TownDirectoryWindow(WindowDesc *desc) : Window(desc) + TownDirectoryWindow(WindowDesc *desc) : Window(desc), townname_editbox(MAX_LENGTH_TOWN_NAME_CHARS * MAX_CHAR_LENGTH, MAX_LENGTH_TOWN_NAME_CHARS) { this->CreateNestedTree(); @@ -751,6 +755,9 @@ public: this->BuildSortTownList(); this->FinishInitNested(0); + + this->querystrings[WID_TD_FILTER] = &this->townname_editbox; + this->townname_editbox.cancel_button = QueryString::ACTION_CLEAR; } void SetStringParameters(int widget) const override @@ -941,6 +948,14 @@ public: this->vscroll->SetCapacityFromWidget(this, WID_TD_LIST); } + virtual void OnEditboxChanged(int wid) + { + if (wid == WID_TD_FILTER) { + this->string_filter.SetFilterTerm(this->townname_editbox.text.buf); + this->InvalidateData(TDIWD_FILTER_CHANGES); + } + } + /** * Some data on this window has become invalid. * @param data Information about the changed data. @@ -948,11 +963,41 @@ public: */ void OnInvalidateData(int data = 0, bool gui_scope = true) override { - if (data == 0) { - /* This needs to be done in command-scope to enforce rebuilding before resorting invalid data */ - this->towns.ForceRebuild(); - } else { - this->towns.ForceResort(); + char buf[MAX_LENGTH_TOWN_NAME_CHARS * MAX_CHAR_LENGTH]; + + switch (data) { + case TDIWD_FORCE_REBUILD: + /* This needs to be done in command-scope to enforce rebuilding before resorting invalid data */ + this->towns.ForceRebuild(); + break; + + case TDIWD_FILTER_CHANGES: + if (this->string_filter.IsEmpty()) { + this->towns.ForceRebuild(); + } else { + this->towns.clear(); + + const Town *t; + FOR_ALL_TOWNS(t) { + this->string_filter.ResetState(); + + SetDParam(0, t->index); + GetString(buf, STR_TOWN_NAME, lastof(buf)); + + this->string_filter.AddLine(buf); + if (this->string_filter.GetState()) this->towns.push_back(t); + } + + this->towns.SetListing(this->last_sorting); + this->towns.ForceResort(); + this->towns.Sort(); + this->towns.shrink_to_fit(); + this->towns.RebuildDone(); + this->vscroll->SetCount(this->towns.size()); // Update scrollbar as well. + } + break; + default: + this->towns.ForceResort(); } } }; diff --git a/src/widgets/town_widget.h b/src/widgets/town_widget.h index 2559423ce..e5ac66184 100644 --- a/src/widgets/town_widget.h +++ b/src/widgets/town_widget.h @@ -16,6 +16,7 @@ enum TownDirectoryWidgets { WID_TD_SORT_ORDER, ///< Direction of sort dropdown. WID_TD_SORT_CRITERIA, ///< Criteria of sort dropdown. + WID_TD_FILTER, ///< Filter of name. WID_TD_LIST, ///< List of towns. WID_TD_SCROLLBAR, ///< Scrollbar for the town list. WID_TD_WORLD_POPULATION, ///< The world's population. |