summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTELK <telk5093@gmail.com>2019-07-23 04:27:39 +0900
committerCharles Pigott <charlespigott@googlemail.com>2019-07-22 20:27:39 +0100
commit196d586849684e62aa9a40093f2a1ce60e1cd53f (patch)
tree519f846ac8a112571e46127fed937aa5008e5699 /src
parentd71a7c21da27e5f99e48b8ad21b669d078932e35 (diff)
downloadopenttd-196d586849684e62aa9a40093f2a1ce60e1cd53f.tar.xz
Feature: Town name filtering (#7621)
Diffstat (limited to 'src')
-rw-r--r--src/script/api/game/game_window.hpp.sq1
-rw-r--r--src/script/api/script_window.hpp1
-rw-r--r--src/town.h6
-rw-r--r--src/town_gui.cpp63
-rw-r--r--src/widgets/town_widget.h1
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.