From a6ce29d209642872e27e6695ad4867a9648ac843 Mon Sep 17 00:00:00 2001 From: Myk Taylor Date: Wed, 1 Nov 2023 23:56:56 -0700 Subject: [PATCH] remove old code for search plugin (now part of sort) --- conf.py | 3 +- docs/about/Removed.rst | 6 + docs/images/search-stockpile.png | Bin 5132 -> 0 bytes docs/images/search.png | Bin 4509 -> 0 bytes docs/plugins/search.rst | 52 - docs/plugins/sort.rst | 8 +- plugins/CMakeLists.txt | 1 - plugins/search.cpp | 2568 ------------------------------ 8 files changed, 12 insertions(+), 2626 deletions(-) delete mode 100644 docs/images/search-stockpile.png delete mode 100644 docs/images/search.png delete mode 100644 docs/plugins/search.rst delete mode 100644 plugins/search.cpp diff --git a/conf.py b/conf.py index 60c3be579..ffcc24b75 100644 --- a/conf.py +++ b/conf.py @@ -78,8 +78,7 @@ def write_tool_docs(): os.makedirs(os.path.join('docs/tools', os.path.dirname(k[0])), mode=0o755, exist_ok=True) with write_file_if_changed('docs/tools/{}.rst'.format(k[0])) as outfile: - if k[0] != 'search': - outfile.write(label) + outfile.write(label) outfile.write(include) diff --git a/docs/about/Removed.rst b/docs/about/Removed.rst index 86d7e0f75..67c4530bb 100644 --- a/docs/about/Removed.rst +++ b/docs/about/Removed.rst @@ -220,6 +220,12 @@ ruby Support for the Ruby language in DFHack scripts was removed due to the issues the Ruby library causes when used as an embedded language. +.. _search-plugin: + +search +====== +Functionality was merged into `sort`. + .. _show-unit-syndromes: show-unit-syndromes diff --git a/docs/images/search-stockpile.png b/docs/images/search-stockpile.png deleted file mode 100644 index a0e837875c86685bc421549199ae5f6f7438ff87..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5132 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 Kfvq<1jQtNc4N)Wj diff --git a/docs/images/search.png b/docs/images/search.png deleted file mode 100644 index 384c3c533214d92769818d9d357293208a11e507..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4509 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 cur; cur = cur->child) - if (cur == screen && cur->breakdown_level == interface_breakdown_types::NONE) - return true; - return false; -} - -static string get_unit_description(df::unit *unit) -{ - if (!unit) - return ""; - string desc; - auto name = Units::getVisibleName(unit); - if (name->has_name) - desc = Translation::TranslateName(name, false); - desc += ", " + Units::getProfessionName(unit); // Check animal type too - - return desc; -} - -static bool cursor_key_pressed (std::set *input, bool in_entry_mode) -{ - if (in_entry_mode) - { - // give text input (e.g. "2") priority over cursor keys - for (auto it = input->begin(); it != input->end(); ++it) - { - if (Screen::keyToChar(*it) != -1) - return false; - } - } - return - input->count(df::interface_key::CURSOR_UP) || - input->count(df::interface_key::CURSOR_DOWN) || - input->count(df::interface_key::CURSOR_LEFT) || - input->count(df::interface_key::CURSOR_RIGHT) || - input->count(df::interface_key::CURSOR_UPLEFT) || - input->count(df::interface_key::CURSOR_UPRIGHT) || - input->count(df::interface_key::CURSOR_DOWNLEFT) || - input->count(df::interface_key::CURSOR_DOWNRIGHT) || - input->count(df::interface_key::CURSOR_UP_FAST) || - input->count(df::interface_key::CURSOR_DOWN_FAST) || - input->count(df::interface_key::CURSOR_LEFT_FAST) || - input->count(df::interface_key::CURSOR_RIGHT_FAST) || - input->count(df::interface_key::CURSOR_UPLEFT_FAST) || - input->count(df::interface_key::CURSOR_UPRIGHT_FAST) || - input->count(df::interface_key::CURSOR_DOWNLEFT_FAST) || - input->count(df::interface_key::CURSOR_DOWNRIGHT_FAST) || - input->count(df::interface_key::CURSOR_UP_Z) || - input->count(df::interface_key::CURSOR_DOWN_Z) || - input->count(df::interface_key::CURSOR_UP_Z_AUX) || - input->count(df::interface_key::CURSOR_DOWN_Z_AUX); -} - -// -// START: Generic Search functionality -// - -template -class search_generic -{ -public: - bool init(S *screen) - { - if (screen != viewscreen && !reset_on_change()) - return false; - - if (!can_init(screen)) - { - if (is_valid()) - { - clear_search(); - reset_all(); - } - - return false; - } - - if (!is_valid()) - { - this->viewscreen = screen; - this->cursor_pos = get_viewscreen_cursor(); - this->primary_list = get_primary_list(); - this->select_key = get_search_select_key(); - select_token = Screen::charToKey(select_key); - shift_select_token = Screen::charToKey(select_key + 'A' - 'a'); - valid = true; - do_post_init(); - } - - return true; - } - - // Called each time you enter or leave a searchable screen. Resets everything. - virtual void reset_all() - { - reset_search(); - valid = false; - primary_list = NULL; - viewscreen = NULL; - select_key = 's'; - } - - bool reset_on_change() - { - if (valid && is_live_screen(viewscreen)) - return false; - - reset_all(); - return true; - } - - bool is_valid() - { - return valid; - } - - // A new keystroke is received in a searchable screen - virtual bool process_input(set *input) - { - // If the page has two search options (Trade screen), only allow one to operate - // at a time - if (lock != NULL && lock != this) - return false; - - // Allows custom preprocessing for each screen - if (!should_check_input(input)) - return false; - - bool key_processed = true; - - if (entry_mode) - { - // Query typing mode - - df::interface_key last_token = get_string_key(input); - int charcode = Screen::keyToChar(last_token); - if (charcode >= 32 && charcode <= 126) - { - // Standard character - search_string += char(charcode); - do_search(); - } - else if (last_token == interface_key::STRING_A000) - { - // Backspace - if (search_string.length() > 0) - { - search_string.erase(search_string.length()-1); - do_search(); - } - } - else if (input->count(interface_key::SELECT) || input->count(interface_key::LEAVESCREEN)) - { - // ENTER or ESC: leave typing mode - end_entry_mode(); - } - else if (cursor_key_pressed(input, entry_mode)) - { - // Arrow key pressed. Leave entry mode and allow screen to process key - end_entry_mode(); - key_processed = false; - } - } - // Not in query typing mode - else if (input->count(select_token)) - { - // Hotkey pressed, enter typing mode - start_entry_mode(); - } - else if (input->count(shift_select_token)) - { - // Shift + Hotkey pressed, clear query - clear_search(); - } - else - { - // Not a key for us, pass it on to the screen - key_processed = false; - } - - return key_processed || entry_mode; // Only pass unrecognized keys down if not in typing mode - } - - // Called after a keystroke has been processed - virtual void do_post_input_feed() - { - } - - static search_generic *lock; - - bool in_entry_mode() - { - return entry_mode; - } - -protected: - virtual string get_element_description(T element) const = 0; - virtual void render() const = 0; - virtual int32_t *get_viewscreen_cursor() = 0; - virtual vector *get_primary_list() = 0; - - search_generic() - { - reset_all(); - } - - virtual bool can_init(S *screen) - { - return true; - } - - virtual void do_post_init() - { - - } - - void start_entry_mode() - { - entry_mode = true; - lock = this; - } - - void end_entry_mode() - { - entry_mode = false; - lock = NULL; - } - - virtual char get_search_select_key() - { - return 's'; - } - - virtual void reset_search() - { - end_entry_mode(); - search_string = ""; - saved_list1.clear(); - } - - // Shortcut to clear the search immediately - virtual void clear_search() - { - if (saved_list1.size() > 0) - { - *primary_list = saved_list1; - saved_list1.clear(); - } - search_string = ""; - } - - virtual void save_original_values() - { - saved_list1 = *primary_list; - } - - virtual void do_pre_incremental_search() - { - - } - - virtual void clear_viewscreen_vectors() - { - primary_list->clear(); - } - - virtual void add_to_filtered_list(size_t i) - { - primary_list->push_back(saved_list1[i]); - } - - virtual void do_post_search() - { - - } - - virtual bool is_valid_for_search(size_t index) - { - return true; - } - - virtual bool force_in_search(size_t index) - { - return false; - } - - // The actual sort - virtual void do_search() - { - if (search_string.length() == 0) - { - clear_search(); - return; - } - - if (saved_list1.size() == 0) - // On first run, save the original list - save_original_values(); - else - do_pre_incremental_search(); - - clear_viewscreen_vectors(); - - string search_string_l = to_search_normalized(search_string); - for (size_t i = 0; i < saved_list1.size(); i++ ) - { - if (force_in_search(i)) - { - add_to_filtered_list(i); - continue; - } - - if (!is_valid_for_search(i)) - continue; - - T element = saved_list1[i]; - string desc = to_search_normalized(get_element_description(element)); - if (desc.find(search_string_l) != string::npos) - { - add_to_filtered_list(i); - } - } - - do_post_search(); - - if (cursor_pos) - *cursor_pos = 0; - } - - virtual bool should_check_input(set *input) - { - return true; - } - - // Display hotkey message - void print_search_option(int x, int y = -1) const - { - auto dim = Screen::getWindowSize(); - if (y == -1) - y = dim.y - 2; - - OutputString((entry_mode) ? 4 : 12, x, y, string(1, select_key)); - OutputString((entry_mode) ? 10 : 15, x, y, ": Search"); - if (search_string.length() > 0 || entry_mode) - OutputString(15, x, y, ": " + search_string); - if (entry_mode) - OutputString(10, x, y, "_"); - } - - S *viewscreen; - vector saved_list1, reference_list, *primary_list; - - //bool redo_search; - string search_string; - -protected: - int *cursor_pos; - char select_key; - bool valid; - bool entry_mode; - - df::interface_key select_token; - df::interface_key shift_select_token; -}; - -template search_generic *search_generic ::lock = NULL; - - -// Search class helper for layered screens -template -class layered_search : public search_generic -{ -protected: - virtual bool can_init(S *screen) - { - auto list = getLayerList(screen); - if (!is_list_valid(screen) || !list || !list->active) - return false; - - return true; - } - - virtual bool is_list_valid(S*) - { - return true; - } - - virtual void do_search() - { - search_generic::do_search(); - auto list = getLayerList(this->viewscreen); - list->num_entries = this->get_primary_list()->size(); - } - - int32_t *get_viewscreen_cursor() - { - auto list = getLayerList(this->viewscreen); - return &list->cursor; - } - - virtual void clear_search() - { - search_generic::clear_search(); - - if (is_list_valid(this->viewscreen)) - { - auto list = getLayerList(this->viewscreen); - list->num_entries = this->get_primary_list()->size(); - } - } - -private: - static df::layer_object_listst *getLayerList(const df::viewscreen_layer *layer) - { - return virtual_cast(vector_get(layer->layer_objects, LIST_ID)); - } -}; - - - -// Parent class for screens that have more than one primary list to synchronise -template < class S, class T, class PARENT = search_generic > -class search_multicolumn_modifiable_generic : public PARENT -{ -protected: - vector reference_list; - vector saved_indexes; - bool read_only; - - virtual void update_saved_secondary_list_item(size_t i, size_t j) = 0; - virtual void save_secondary_values() = 0; - virtual void clear_secondary_viewscreen_vectors() = 0; - virtual void add_to_filtered_secondary_lists(size_t i) = 0; - virtual void clear_secondary_saved_lists() = 0; - virtual void reset_secondary_viewscreen_vectors() = 0; - virtual void restore_secondary_values() = 0; - - virtual void do_post_init() - { - // If true, secondary list isn't modifiable so don't bother synchronising values - read_only = false; - } - - void reset_all() - { - PARENT::reset_all(); - reference_list.clear(); - saved_indexes.clear(); - reset_secondary_viewscreen_vectors(); - } - - void reset_search() - { - PARENT::reset_search(); - reference_list.clear(); - saved_indexes.clear(); - clear_secondary_saved_lists(); - } - - virtual void clear_search() - { - if (this->saved_list1.size() > 0) - { - do_pre_incremental_search(); - restore_secondary_values(); - } - clear_secondary_saved_lists(); - PARENT::clear_search(); - do_post_search(); - } - - virtual bool is_match(T &a, T &b) = 0; - - virtual bool is_match(vector &a, vector &b) = 0; - - void do_pre_incremental_search() - { - PARENT::do_pre_incremental_search(); - if (read_only) - return; - - bool list_has_been_sorted = (this->primary_list->size() == reference_list.size() - && !is_match(*this->primary_list, reference_list)); - - for (size_t i = 0; i < saved_indexes.size(); i++) - { - int adjusted_item_index = i; - if (list_has_been_sorted) - { - for (size_t j = 0; j < this->primary_list->size(); j++) - { - if (is_match((*this->primary_list)[j], reference_list[i])) - { - adjusted_item_index = j; - break; - } - } - } - - update_saved_secondary_list_item(saved_indexes[i], adjusted_item_index); - } - saved_indexes.clear(); - } - - void clear_viewscreen_vectors() - { - search_generic::clear_viewscreen_vectors(); - saved_indexes.clear(); - clear_secondary_viewscreen_vectors(); - } - - void add_to_filtered_list(size_t i) - { - search_generic::add_to_filtered_list(i); - add_to_filtered_secondary_lists(i); - if (!read_only) - saved_indexes.push_back(i); // Used to map filtered indexes back to original, if needed - } - - virtual void do_post_search() - { - if (!read_only) - reference_list = *this->primary_list; - } - - void save_original_values() - { - search_generic::save_original_values(); - save_secondary_values(); - } -}; - -// This basic match function is separated out from the generic multi column class, because the -// pets screen, which uses a union in its primary list, will cause a compile failure if this -// match function exists in the generic class -template < class S, class T, class PARENT = search_generic > -class search_multicolumn_modifiable : public search_multicolumn_modifiable_generic -{ - bool is_match(T &a, T &b) - { - return a == b; - } - - bool is_match(vector &a, vector &b) - { - return a == b; - } -}; - -// General class for screens that have only one secondary list to keep in sync -template < class S, class T, class V, class PARENT = search_generic > -class search_twocolumn_modifiable : public search_multicolumn_modifiable -{ -public: -protected: - virtual vector * get_secondary_list() = 0; - - virtual void do_post_init() - { - search_multicolumn_modifiable::do_post_init(); - secondary_list = get_secondary_list(); - } - - void save_secondary_values() - { - saved_secondary_list = *secondary_list; - } - - void reset_secondary_viewscreen_vectors() - { - secondary_list = NULL; - } - - virtual void update_saved_secondary_list_item(size_t i, size_t j) - { - saved_secondary_list[i] = (*secondary_list)[j]; - } - - void clear_secondary_viewscreen_vectors() - { - secondary_list->clear(); - } - - void add_to_filtered_secondary_lists(size_t i) - { - secondary_list->push_back(saved_secondary_list[i]); - } - - void clear_secondary_saved_lists() - { - saved_secondary_list.clear(); - } - - void restore_secondary_values() - { - *secondary_list = saved_secondary_list; - } - - vector *secondary_list, saved_secondary_list; -}; - - -// Parent struct for the hooks, use optional param D to generate multiple search classes in the same -// viewscreen but different static modules -template -struct generic_search_hook : T -{ - typedef T interpose_base; - - static V module; - - DEFINE_VMETHOD_INTERPOSE(void, feed, (set *input)) - { - if (!module.init(this)) - { - INTERPOSE_NEXT(feed)(input); - return; - } - - if (!module.process_input(input)) - { - INTERPOSE_NEXT(feed)(input); - module.do_post_input_feed(); - } - - } - - DEFINE_VMETHOD_INTERPOSE(void, render, ()) - { - bool ok = module.init(this); - INTERPOSE_NEXT(render)(); - if (ok) - module.render(); - } - - DEFINE_VMETHOD_INTERPOSE(bool, key_conflict, (df::interface_key key)) - { - if (module.in_entry_mode() && (key == interface_key::MOVIES || key == interface_key::HELP)) - return true; - return INTERPOSE_NEXT(key_conflict)(key); - } -}; - -template V generic_search_hook ::module; - - -// Hook definition helpers -#define IMPLEMENT_HOOKS_WITH_ID(screen, module, id, prio) \ - typedef generic_search_hook module##_hook; \ - template<> IMPLEMENT_VMETHOD_INTERPOSE_PRIO(module##_hook, feed, prio); \ - template<> IMPLEMENT_VMETHOD_INTERPOSE_PRIO(module##_hook, render, prio); \ - template<> IMPLEMENT_VMETHOD_INTERPOSE_PRIO(module##_hook, key_conflict, prio) - -#define IMPLEMENT_HOOKS(screen, module) \ - typedef generic_search_hook module##_hook; \ - template<> IMPLEMENT_VMETHOD_INTERPOSE(module##_hook, feed); \ - template<> IMPLEMENT_VMETHOD_INTERPOSE(module##_hook, render); \ - template<> IMPLEMENT_VMETHOD_INTERPOSE(module##_hook, key_conflict) - -#define IMPLEMENT_HOOKS_PRIO(screen, module, prio) \ - typedef generic_search_hook module##_hook; \ - template<> IMPLEMENT_VMETHOD_INTERPOSE_PRIO(module##_hook, feed, prio); \ - template<> IMPLEMENT_VMETHOD_INTERPOSE_PRIO(module##_hook, render, prio); \ - template<> IMPLEMENT_VMETHOD_INTERPOSE_PRIO(module##_hook, key_conflict, prio); - -// -// END: Generic Search functionality -// - - -// -// START: Animal screen search -// - -typedef search_multicolumn_modifiable_generic pets_search_base; -class pets_search : public pets_search_base -{ - typedef df::viewscreen_petst::T_animal T_animal; - typedef df::viewscreen_petst::T_mode T_mode; -public: - void render() const - { - print_search_option(25, 4); - } - -private: - bool can_init(df::viewscreen_petst *screen) - { - return pets_search_base::can_init(screen) && screen->mode == T_mode::List; - } - - int32_t *get_viewscreen_cursor() - { - return &viewscreen->cursor; - } - - vector *get_primary_list() - { - return &viewscreen->animal; - } - - virtual void do_post_init() - { - is_vermin = &viewscreen->is_vermin; - is_tame = &viewscreen->is_tame; - is_adopting = &viewscreen->is_adopting; - } - - string get_element_description(df::viewscreen_petst::T_animal element) const - { - return get_unit_description(element.unit); - } - - bool should_check_input() - { - return viewscreen->mode == T_mode::List; - } - - bool is_valid_for_search(size_t i) - { - return is_vermin_s[i] == 0; - } - - void save_secondary_values() - { - is_vermin_s = *is_vermin; - is_tame_s = *is_tame; - is_adopting_s = *is_adopting; - } - - void reset_secondary_viewscreen_vectors() - { - is_vermin = NULL; - is_tame = NULL; - is_adopting = NULL; - } - - void update_saved_secondary_list_item(size_t i, size_t j) - { - is_vermin_s[i] = (*is_vermin)[j]; - is_tame_s[i] = (*is_tame)[j]; - is_adopting_s[i] = (*is_adopting)[j]; - } - - void clear_secondary_viewscreen_vectors() - { - is_vermin->clear(); - is_tame->clear(); - is_adopting->clear(); - } - - void add_to_filtered_secondary_lists(size_t i) - { - is_vermin->push_back(is_vermin_s[i]); - is_tame->push_back(is_tame_s[i]); - is_adopting->push_back(is_adopting_s[i]); - } - - void clear_secondary_saved_lists() - { - is_vermin_s.clear(); - is_tame_s.clear(); - is_adopting_s.clear(); - } - - void restore_secondary_values() - { - *is_vermin = is_vermin_s; - *is_tame = is_tame_s; - *is_adopting = is_adopting_s; - } - - bool is_match(T_animal &a, T_animal &b) - { - return a.unit == b.unit; - } - - bool is_match(vector &a, vector &b) - { - for (size_t i = 0; i < a.size(); i++) - { - if (!is_match(a[i], b[i])) - return false; - } - - return true; - } - - std::vector *is_vermin, is_vermin_s; - std::vector *is_tame, is_tame_s; - std::vector *is_adopting, is_adopting_s; -}; - -IMPLEMENT_HOOKS_WITH_ID(df::viewscreen_petst, pets_search, 1, 0); - -// -// END: Animal screen search -// - - -// -// START: Animal knowledge screen search -// - -typedef search_generic animal_knowledge_search_base; -class animal_knowledge_search : public animal_knowledge_search_base -{ - typedef df::viewscreen_petst::T_mode T_mode; - bool can_init(df::viewscreen_petst *screen) - { - return animal_knowledge_search_base::can_init(screen) && screen->mode == T_mode::TrainingKnowledge; - } - -public: - void render() const - { - print_search_option(2, 4); - } - -private: - int32_t *get_viewscreen_cursor() - { - return NULL; - } - - vector *get_primary_list() - { - return &viewscreen->known; - } - - string get_element_description(int32_t id) const - { - auto craw = df::creature_raw::find(id); - string out; - if (craw) - { - for (size_t i = 0; i < 3; ++i) - out += craw->name[i] + " "; - } - return out; - } -}; - -IMPLEMENT_HOOKS_WITH_ID(df::viewscreen_petst, animal_knowledge_search, 2, 0); - -// -// END: Animal knowledge screen search -// - - -// -// START: Animal trainer search -// - -typedef search_twocolumn_modifiable animal_trainer_search_base; -class animal_trainer_search : public animal_trainer_search_base -{ - typedef df::viewscreen_petst::T_mode T_mode; - typedef df::viewscreen_petst::T_trainer_mode T_trainer_mode; - - bool can_init(df::viewscreen_petst *screen) - { - return animal_trainer_search_base::can_init(screen) && screen->mode == T_mode::SelectTrainer; - } - -public: - void render() const - { - Screen::paintTile(Screen::Pen('\xBA', 8, 0), 14, 2); - Screen::paintTile(Screen::Pen('\xBA', 8, 0), gps->dimx - 14, 2); - Screen::paintTile(Screen::Pen('\xC9', 8, 0), 14, 1); - Screen::paintTile(Screen::Pen('\xBB', 8, 0), gps->dimx - 14, 1); - for (int x = 15; x <= gps->dimx - 15; ++x) - { - Screen::paintTile(Screen::Pen('\xCD', 8, 0), x, 1); - Screen::paintTile(Screen::Pen('\x00', 0, 0), x, 2); - } - print_search_option(16, 2); - } - -private: - int32_t *get_viewscreen_cursor() - { - return &viewscreen->trainer_cursor; - } - - vector *get_primary_list() - { - return &viewscreen->trainer_unit; - } - - string get_element_description(df::unit *u) const - { - return get_unit_description(u); - } - - std::vector *get_secondary_list() - { - return &viewscreen->trainer_mode; - } - -public: - bool process_input(set *input) - { - if (input->count(interface_key::SELECT) && viewscreen->trainer_unit.empty() && !in_entry_mode()) - return true; - return animal_trainer_search_base::process_input(input); - } - -}; - -IMPLEMENT_HOOKS_WITH_ID(df::viewscreen_petst, animal_trainer_search, 3, 0); - -// -// END: Animal trainer search -// - - -// -// START: Stocks screen search -// -typedef search_generic stocks_search_base; -class stocks_search : public stocks_search_base -{ -public: - - void render() const - { - if (!viewscreen->in_group_mode) - print_search_option(2); - else - { - auto dim = Screen::getWindowSize(); - int x = 2, y = dim.y - 2; - OutputString(15, x, y, "Tab to enable Search"); - } - } - - bool process_input(set *input) - { - if (viewscreen->in_group_mode) - return false; - - redo_search = false; - - if ((input->count(interface_key::CURSOR_UP) || input->count(interface_key::CURSOR_DOWN)) && !viewscreen->in_right_list) - { - // Redo search if category changes - saved_list1.clear(); - end_entry_mode(); - if (search_string.length() > 0) - redo_search = true; - - return false; - } - - return stocks_search_base::process_input(input); - } - - virtual void do_post_input_feed() - { - if (viewscreen->in_group_mode) - { - // Disable search if item lists are grouped - clear_search(); - reset_search(); - } - else if (redo_search) - { - do_search(); - redo_search = false; - } - } - -private: - int32_t *get_viewscreen_cursor() - { - return &viewscreen->item_cursor; - } - - virtual vector *get_primary_list() - { - return &viewscreen->items; - } - - -private: - string get_element_description(df::item *element) const - { - if (!element) - return ""; - return Items::getDescription(element, 0, true); - } - - bool redo_search; -}; - - -IMPLEMENT_HOOKS_PRIO(df::viewscreen_storesst, stocks_search, 100); - -// -// END: Stocks screen search -// - - -// -// START: Unit screen search -// -typedef search_twocolumn_modifiable unitlist_search_base; -class unitlist_search : public unitlist_search_base -{ -public: - void render() const - { - print_search_option(28); - } - -private: - void do_post_init() - { - unitlist_search_base::do_post_init(); - read_only = true; - } - - static string get_non_work_description(df::unit *unit) - { - if (!unit) - return ""; - for (auto p = unit->status.misc_traits.begin(); p < unit->status.misc_traits.end(); p++) - { - if ((*p)->id == misc_trait_type::Migrant) - { - return ".new arrival.migrant"; - } - } - - if (Units::isBaby(unit) || - Units::isChild(unit) || - unit->profession == profession::DRUNK) - { - return ""; - } - - if (ENUM_ATTR(profession, military, unit->profession)) - return ".military"; - - return ".idle.no job"; - } - - string get_element_description(df::unit *unit) const - { - if (!unit) - return "Inactive"; - string desc = get_unit_description(unit); - if (!unit->job.current_job) - { - desc += get_non_work_description(unit); - } - - return desc; - } - - bool should_check_input(set *input) - { - if (input->count(interface_key::STANDARDSCROLL_LEFT) || - input->count(interface_key::STANDARDSCROLL_RIGHT) || - (!in_entry_mode() && input->count(interface_key::UNITVIEW_PRF_PROF))) - { - if (!in_entry_mode()) - { - // Changing screens, reset search - int32_t *cursor_pos = get_viewscreen_cursor(); - if (cursor_pos && *cursor_pos < 0) - *cursor_pos = 0; - clear_search(); - reset_all(); - return false; - } - else - { - // Ignore cursor keys when typing - input->erase(interface_key::STANDARDSCROLL_LEFT); - input->erase(interface_key::STANDARDSCROLL_RIGHT); - } - } - - return true; - } - - char get_search_select_key() - { - return 'q'; - } - - vector *get_secondary_list() - { - return &viewscreen->jobs[viewscreen->page]; - } - - int32_t *get_viewscreen_cursor() - { - return &viewscreen->cursor_pos[viewscreen->page]; - } - - vector *get_primary_list() - { - return &viewscreen->units[viewscreen->page]; - } -}; - -typedef generic_search_hook unitlist_search_hook; -IMPLEMENT_HOOKS_PRIO(df::viewscreen_unitlistst, unitlist_search, 100); - -// -// END: Unit screen search -// - - -// -// START: Trade screen search -// -class trade_search_base : public search_multicolumn_modifiable -{ -protected: - virtual vector *get_selected_list() = 0; - virtual vector *get_count_list() = 0; - -private: - string get_element_description(df::item *element) const - { - if (!element) - return ""; - return Items::getDescription(element, 0, true); - } - - bool should_check_input(set *input) - { - if (in_entry_mode()) - return true; - - if (input->count(interface_key::TRADE_TRADE) || - input->count(interface_key::TRADE_OFFER) || - input->count(interface_key::TRADE_SEIZE)) - { - // Block the keys if were searching - if (!search_string.empty()) - { - input->clear(); - } - - return false; - } - else if (input->count(interface_key::CUSTOM_ALT_C)) - { - clear_search_for_trade(); - return true; - } - - return true; - } - - void clear_search_for_trade() - { - // Trying to trade, reset search - clear_search(); - reset_all(); - } - - void do_post_init() - { - search_multicolumn_modifiable::do_post_init(); - - selected = get_selected_list(); - count = get_count_list(); - } - - void save_secondary_values() - { - selected_s = *selected; - count_s = *count; - } - - void reset_secondary_viewscreen_vectors() - { - selected = NULL; - count = NULL; - } - - void update_saved_secondary_list_item(size_t i, size_t j) - { - selected_s[i] = (*selected)[j]; - count_s[i] = (*count)[j]; - } - - void clear_secondary_viewscreen_vectors() - { - selected->clear(); - count->clear(); - } - - void add_to_filtered_secondary_lists(size_t i) - { - selected->push_back(selected_s[i]); - count->push_back(count_s[i]); - } - - void clear_secondary_saved_lists() - { - selected_s.clear(); - count_s.clear(); - } - - void restore_secondary_values() - { - *selected = selected_s; - *count = count_s; - } - - std::vector *selected, selected_s; - std::vector *count, count_s; -}; - - -class trade_search_merc : public trade_search_base -{ -public: - virtual void render() const - { - if (viewscreen->counteroffer.size() > 0) - { - // The merchant is proposing a counteroffer. - // Not only is there nothing to search, - // but the native hotkeys are where we normally write. - return; - } - - print_search_option(2, -1); - - if (!search_string.empty()) - { - int32_t x = 2; - int32_t y = gps->dimy - 3; - make_text_dim(2, gps->dimx-2, y); - OutputString(COLOR_LIGHTRED, x, y, string(1, select_key + 'A' - 'a')); - OutputString(COLOR_WHITE, x, y, ": Clear search to trade "); - } - } - -private: - int32_t *get_viewscreen_cursor() - { - return &viewscreen->trader_cursor; - } - - vector *get_primary_list() - { - return &viewscreen->trader_items; - } - - vector *get_selected_list() - { - return &viewscreen->trader_selected; - } - - vector *get_count_list() - { - return &viewscreen->trader_count; - } - - char get_search_select_key() - { - return 'q'; - } -}; - -IMPLEMENT_HOOKS_WITH_ID(df::viewscreen_tradegoodsst, trade_search_merc, 1, 100); - - -class trade_search_fort : public trade_search_base -{ -public: - virtual void render() const - { - if (viewscreen->counteroffer.size() > 0) - { - // The merchant is proposing a counteroffer. - // Not only is there nothing to search, - // but the native hotkeys are where we normally write. - return; - } - - int32_t x = gps->dimx / 2 + 2; - print_search_option(x, -1); - - if (!search_string.empty()) - { - int32_t y = gps->dimy - 3; - make_text_dim(2, gps->dimx-2, y); - OutputString(COLOR_LIGHTRED, x, y, string(1, select_key + 'A' - 'a')); - OutputString(COLOR_WHITE, x, y, ": Clear search to trade "); - } - } - -private: - int32_t *get_viewscreen_cursor() - { - return &viewscreen->broker_cursor; - } - - vector *get_primary_list() - { - return &viewscreen->broker_items; - } - - vector *get_selected_list() - { - return &viewscreen->broker_selected; - } - - vector *get_count_list() - { - return &viewscreen->broker_count; - } - - char get_search_select_key() - { - return 'w'; - } -}; - -IMPLEMENT_HOOKS_WITH_ID(df::viewscreen_tradegoodsst, trade_search_fort, 2, 100); - -// -// END: Trade screen search -// - - -// -// START: Stockpile screen search -// -typedef layered_search stocks_layer; -class stockpile_search : public search_twocolumn_modifiable -{ -public: - void update_saved_secondary_list_item(size_t i, size_t j) - { - *saved_secondary_list[i] = *(*secondary_list)[j]; - } - - string get_element_description(string *element) const - { - return *element; - } - - void render() const - { - print_search_option(51, 23); - } - - vector *get_primary_list() - { - return &viewscreen->item_names; - } - - vector *get_secondary_list() - { - return &viewscreen->item_status; - } - - bool should_check_input(set *input) - { - if (input->count(interface_key::STOCKPILE_SETTINGS_DISABLE) && !in_entry_mode() && !search_string.empty()) - { - // Restore original list - clear_search(); - reset_all(); - } - - return true; - } - -}; - -IMPLEMENT_HOOKS(df::viewscreen_layer_stockpilest, stockpile_search); - -// -// END: Stockpile screen search -// - - -// -// START: Military screen search -// -typedef layered_search military_search_base; -class military_search : public military_search_base -{ -public: - - string get_element_description(df::unit *element) const - { - return get_unit_description(element); - } - - void render() const - { - print_search_option(52, 22); - } - - char get_search_select_key() - { - return 'q'; - } - - // When not on the positions page, this list is used for something - // else entirely, so screwing with it seriously breaks stuff. - bool is_list_valid(df::viewscreen_layer_militaryst *screen) - { - if (screen->page != df::viewscreen_layer_militaryst::Positions) - return false; - - return true; - } - - vector *get_primary_list() - { - return &viewscreen->positions.candidates; - } - - bool should_check_input(set *input) - { - if (input->count(interface_key::SELECT) && !in_entry_mode() && !search_string.empty()) - { - // About to make an assignment, so restore original list (it will be changed by the game) - int32_t *cursor = get_viewscreen_cursor(); - auto list = get_primary_list(); - if (size_t(*cursor) >= list->size()) - return false; - df::unit *selected_unit = list->at(*cursor); - clear_search(); - - for (*cursor = 0; size_t(*cursor) < list->size(); (*cursor)++) - { - if (list->at(*cursor) == selected_unit) - break; - } - - reset_all(); - } - - return true; - } -}; - -IMPLEMENT_HOOKS_PRIO(df::viewscreen_layer_militaryst, military_search, 100); - -// -// END: Military screen search -// - - -// -// START: Room list search -// -typedef search_twocolumn_modifiable roomlist_search_base; -class roomlist_search : public roomlist_search_base -{ -public: - void render() const - { - print_search_option(2, 23); - } - -private: - void do_post_init() - { - roomlist_search_base::do_post_init(); - read_only = true; - } - - string get_element_description(df::building *bld) const - { - if (!bld) - return ""; - - string desc; - desc.reserve(100); - if (bld->owner) - desc += get_unit_description(bld->owner); - - desc += "."; - - string room_desc = Buildings::getRoomDescription(bld, nullptr); - desc += room_desc; - if (room_desc.empty()) - { - if (!bld->owner) - desc += "no owner"; - - string name; - bld->getName(&name); - if (!name.empty()) - { - desc += name; - } - } - - return desc; - } - - vector *get_secondary_list() - { - return &viewscreen->room_value; - } - - int32_t *get_viewscreen_cursor() - { - return &viewscreen->cursor; - } - - vector *get_primary_list() - { - return &viewscreen->buildings; - } -}; - -IMPLEMENT_HOOKS(df::viewscreen_buildinglistst, roomlist_search); - -// -// END: Room list search -// - - - -// -// START: Announcement list search -// -class announcement_search : public search_generic -{ -public: - void render() const - { - print_search_option(2, gps->dimy - 3); - } - -private: - int32_t *get_viewscreen_cursor() - { - return &viewscreen->sel_idx; - } - - virtual vector *get_primary_list() - { - return &viewscreen->reports; - } - - -private: - string get_element_description(df::report *element) const - { - if (!element) - return ""; - return element->text; - } -}; - - -IMPLEMENT_HOOKS(df::viewscreen_announcelistst, announcement_search); - -// -// END: Announcement list search -// - - -// -// START: Nobles search list -// -typedef df::viewscreen_layer_noblelistst::T_candidates T_candidates; -typedef layered_search nobles_search_base; -class nobles_search : public nobles_search_base -{ -public: - - string get_element_description(T_candidates *element) const - { - if (!element->unit) - return ""; - - return get_unit_description(element->unit); - } - - void render() const - { - print_search_option(2, 23); - } - - bool force_in_search(size_t index) - { - return index == 0; // Leave Vacant - } - - bool can_init(df::viewscreen_layer_noblelistst *screen) - { - if (screen->mode != df::viewscreen_layer_noblelistst::Appoint) - return false; - - return nobles_search_base::can_init(screen); - } - - vector *get_primary_list() - { - return &viewscreen->candidates; - } -}; - -IMPLEMENT_HOOKS(df::viewscreen_layer_noblelistst, nobles_search); - -// -// END: Nobles search list -// - -// -// START: Workshop profiles search list -// -typedef search_generic profiles_search_base; -class profiles_search : public profiles_search_base -{ -public: - - bool can_init (df::viewscreen_workshop_profilest *screen) - { - return screen->tab == df::viewscreen_workshop_profilest::T_tab::Workers; - } - - string get_element_description(df::unit *element) const - { - return get_unit_description(element); - } - - void render() const - { - print_search_option(2, gps->dimy - 5); - } - - vector *get_primary_list() - { - return &viewscreen->workers; - } - - int32_t *get_viewscreen_cursor() - { - return &viewscreen->worker_idx; - } -}; - -IMPLEMENT_HOOKS(df::viewscreen_workshop_profilest, profiles_search); - -// -// END: Workshop profiles search list -// - - -// -// START: Job list search -// -void get_job_details(string &desc, df::job *job) -{ - string job_name = ENUM_KEY_STR(job_type,job->job_type); - for (size_t i = 0; i < job_name.length(); i++) - { - char c = job_name[i]; - if (c >= 'A' && c <= 'Z') - desc += " "; - desc += c; - } - desc += "."; - - df::item_type itype = ENUM_ATTR(job_type, item, job->job_type); - - MaterialInfo mat(job); - if (itype == item_type::FOOD) - mat.decode(-1); - - if (mat.isValid() || job->material_category.whole) - { - desc += mat.toString(); - desc += "."; - if (job->material_category.whole) - { - desc += bitfield_to_string(job->material_category); - desc += "."; - } - } - - if (!job->reaction_name.empty()) - { - for (size_t i = 0; i < job->reaction_name.length(); i++) - { - if (job->reaction_name[i] == '_') - desc += " "; - else - desc += job->reaction_name[i]; - } - - desc += "."; - } - - if (job->flags.bits.suspend) - desc += "suspended."; -} - -typedef search_twocolumn_modifiable joblist_search_base; -class joblist_search : public joblist_search_base -{ -public: - void render() const - { - print_search_option(2); - } - -private: - void do_post_init() - { - joblist_search_base::do_post_init(); - read_only = true; - } - - string get_element_description(df::job *element) const - { - if (!element) - return "no job.idle"; - - string desc; - desc.reserve(100); - get_job_details(desc, element); - df::unit *worker = DFHack::Job::getWorker(element); - if (worker) - desc += get_unit_description(worker); - else - desc += "Inactive"; - - return desc; - } - - char get_search_select_key() - { - return 'q'; - } - - vector *get_secondary_list() - { - return &viewscreen->units; - } - - int32_t *get_viewscreen_cursor() - { - return &viewscreen->cursor_pos; - } - - vector *get_primary_list() - { - return &viewscreen->jobs; - } -}; - -IMPLEMENT_HOOKS(df::viewscreen_joblistst, joblist_search); - -// -// END: Job list search -// - - -// -// START: Look menu search -// - -typedef search_generic look_menu_search_base; -class look_menu_search : public look_menu_search_base -{ - typedef df::ui_look_list::T_items::T_type elt_type; -public: - bool can_init(df::viewscreen_dwarfmodest *screen) - { - if (plotinfo->main.mode == df::ui_sidebar_mode::LookAround) - { - return look_menu_search_base::can_init(screen); - } - - return false; - } - - string get_element_description(df::ui_look_list::T_items *element) const - { - std::string desc = ""; - switch (element->type) - { - case elt_type::Item: - if (element->data.Item) - desc = Items::getDescription(element->data.Item, 0, true); - break; - case elt_type::Unit: - if (element->data.Unit) - desc = get_unit_description(element->data.Unit); - break; - case elt_type::Building: - if (element->data.Building) - element->data.Building->getName(&desc); - break; - default: - break; - } - return desc; - } - - bool force_in_search (size_t i) - { - df::ui_look_list::T_items *element = saved_list1[i]; - switch (element->type) - { - case elt_type::Item: - case elt_type::Unit: - case elt_type::Building: - return false; - break; - default: - return true; - break; - } - } - - void render() const - { - auto dims = Gui::getDwarfmodeViewDims(); - int left_margin = dims.menu_x1 + 1; - int x = left_margin; - int y = 1; - - print_search_option(x, y); - } - - vector *get_primary_list() - { - return &ui_look_list->items; - } - - virtual int32_t * get_viewscreen_cursor() - { - return ui_look_cursor; - } - - - bool should_check_input(set *input) - { - if (input->count(interface_key::SECONDSCROLL_UP) - || input->count(interface_key::SECONDSCROLL_DOWN) - || input->count(interface_key::SECONDSCROLL_PAGEUP) - || input->count(interface_key::SECONDSCROLL_PAGEDOWN)) - { - end_entry_mode(); - return false; - } - bool hotkey_pressed = - input->lower_bound(interface_key::D_HOTKEY1) != input->upper_bound(interface_key::D_HOTKEY16); - if (cursor_key_pressed(input, in_entry_mode()) || hotkey_pressed) - { - end_entry_mode(); - clear_search(); - return false; - } - - return true; - } -}; - -IMPLEMENT_HOOKS(df::viewscreen_dwarfmodest, look_menu_search); - -// -// END: Look menu search -// - - -// -// START: Burrow assignment search -// - -typedef search_twocolumn_modifiable burrow_search_base; -class burrow_search : public burrow_search_base -{ -public: - bool can_init(df::viewscreen_dwarfmodest *screen) - { - if (plotinfo->main.mode == df::ui_sidebar_mode::Burrows && plotinfo->burrows.in_add_units_mode) - { - return burrow_search_base::can_init(screen); - } - - return false; - } - - string get_element_description(df::unit *element) const - { - return get_unit_description(element); - } - - void render() const - { - auto dims = Gui::getDwarfmodeViewDims(); - int left_margin = dims.menu_x1 + 1; - int x = left_margin; - int y = 23; - - print_search_option(x, y); - } - - vector *get_primary_list() - { - return &plotinfo->burrows.list_units; - } - - vector *get_secondary_list() - { - return &plotinfo->burrows.sel_units; - } - - virtual int32_t * get_viewscreen_cursor() - { - return &plotinfo->burrows.unit_cursor_pos; - } - - - bool should_check_input(set *input) - { - if (input->count(interface_key::SECONDSCROLL_UP) || input->count(interface_key::SECONDSCROLL_DOWN) - || input->count(interface_key::SECONDSCROLL_PAGEUP) || input->count(interface_key::SECONDSCROLL_PAGEDOWN)) - { - end_entry_mode(); - return false; - } - - return true; - } -}; - -IMPLEMENT_HOOKS(df::viewscreen_dwarfmodest, burrow_search); - -// -// END: Burrow assignment search -// - - -// -// START: Room assignment search -// - -typedef search_generic room_assign_search_base; -class room_assign_search : public room_assign_search_base -{ -public: - bool can_init(df::viewscreen_dwarfmodest *screen) - { - if (plotinfo->main.mode == df::ui_sidebar_mode::QueryBuilding && *ui_building_in_assign) - { - return room_assign_search_base::can_init(screen); - } - - return false; - } - - string get_element_description(df::unit *element) const - { - return element ? get_unit_description(element) : "Nobody"; - } - - void render() const - { - auto dims = Gui::getDwarfmodeViewDims(); - int left_margin = dims.menu_x1 + 1; - int x = left_margin; - int y = 19; - - print_search_option(x, y); - } - - vector *get_primary_list() - { - return ui_building_assign_units; - } - - virtual int32_t * get_viewscreen_cursor() - { - return ui_building_item_cursor; - } - - bool should_check_input(set *input) - { - if (input->count(interface_key::SECONDSCROLL_UP) || input->count(interface_key::SECONDSCROLL_DOWN) - || input->count(interface_key::SECONDSCROLL_PAGEUP) || input->count(interface_key::SECONDSCROLL_PAGEDOWN)) - { - end_entry_mode(); - return false; - } - - return true; - } -}; - -IMPLEMENT_HOOKS(df::viewscreen_dwarfmodest, room_assign_search); - -// -// END: Room assignment search -// - -// -// START: Noble suggestion search -// - -typedef search_generic noble_suggest_search_base; -class noble_suggest_search : public noble_suggest_search_base -{ -public: - string get_element_description (int32_t hf_id) const - { - df::historical_figure *histfig = df::historical_figure::find(hf_id); - if (!histfig) - return ""; - df::unit *unit = df::unit::find(histfig->unit_id); - if (!unit) - return ""; - return get_unit_description(unit); - } - - void render() const - { - print_search_option(2, gps->dimy - 4); - } - - vector *get_primary_list() - { - return &viewscreen->candidate_histfig_ids; - } - - virtual int32_t *get_viewscreen_cursor() - { - return &viewscreen->cursor; - } - -}; - -IMPLEMENT_HOOKS(df::viewscreen_topicmeeting_fill_land_holder_positionsst, noble_suggest_search); - -// -// END: Noble suggestion search -// - -// -// START: Location occupation assignment search -// - -typedef search_generic location_assign_occupation_search_base; -class location_assign_occupation_search : public location_assign_occupation_search_base -{ -public: - bool can_init (df::viewscreen_locationsst *screen) - { - return screen->menu == df::viewscreen_locationsst::AssignOccupation; - } - - string get_element_description (df::unit *unit) const - { - return unit ? get_unit_description(unit) : "Nobody"; - } - - void render() const - { - print_search_option(37, gps->dimy - 3); - } - - vector *get_primary_list() - { - return &viewscreen->units; - } - - virtual int32_t *get_viewscreen_cursor() - { - return &viewscreen->unit_idx; - } - -}; - -IMPLEMENT_HOOKS(df::viewscreen_locationsst, location_assign_occupation_search); - -// -// END: Location occupation assignment search -// - -// -// START: Kitchen preferences search -// - -typedef search_multicolumn_modifiable kitchen_pref_search_base; -class kitchen_pref_search : public kitchen_pref_search_base -{ -public: - - string get_element_description(string *s) const override - { - return s ? *s : ""; - } - - void render() const override - { - print_search_option(40, gps->dimy - 2); - } - - int32_t *get_viewscreen_cursor() override - { - return &viewscreen->cursor; - } - - vector *get_primary_list() override - { - return &viewscreen->item_str[viewscreen->page]; - } - - bool should_check_input(set *input) override - { - if (input->count(interface_key::CHANGETAB) || input->count(interface_key::SEC_CHANGETAB)) - { - // Restore original list - clear_search(); - reset_all(); - } - - return true; - } - - -#define KITCHEN_VECTORS \ - KVEC(df::item_type, item_type); \ - KVEC(int16_t, item_subtype); \ - KVEC(int16_t, mat_type); \ - KVEC(int32_t, mat_index); \ - KVEC(int32_t, count); \ - KVEC(df::kitchen_pref_flag, forbidden); \ - KVEC(df::kitchen_pref_flag, possible) - - - virtual void do_post_init() - { - kitchen_pref_search_base::do_post_init(); - #define KVEC(type, name) name = &viewscreen->name[viewscreen->page] - KITCHEN_VECTORS; - #undef KVEC - } - - void save_secondary_values() - { - #define KVEC(type, name) name##_s = *name - KITCHEN_VECTORS; - #undef KVEC - } - - void reset_secondary_viewscreen_vectors() - { - #define KVEC(type, name) name = nullptr - KITCHEN_VECTORS; - #undef KVEC - } - - virtual void update_saved_secondary_list_item(size_t i, size_t j) - { - #define KVEC(type, name) name##_s[i] = (*name)[j]; - KITCHEN_VECTORS; - #undef KVEC - } - - void clear_secondary_viewscreen_vectors() - { - #define KVEC(type, name) name->clear() - KITCHEN_VECTORS; - #undef KVEC - } - - void add_to_filtered_secondary_lists(size_t i) - { - #define KVEC(type, name) name->push_back(name##_s[i]) - KITCHEN_VECTORS; - #undef KVEC - } - - void clear_secondary_saved_lists() - { - #define KVEC(type, name) name##_s.clear() - KITCHEN_VECTORS; - #undef KVEC - } - - void restore_secondary_values() - { - #define KVEC(type, name) *name = name##_s - KITCHEN_VECTORS; - #undef KVEC - } - - #define KVEC(type, name) vector *name, name##_s - KITCHEN_VECTORS; - #undef KVEC -#undef KITCHEN_VECTORS -}; - -IMPLEMENT_HOOKS(df::viewscreen_kitchenprefst, kitchen_pref_search); - -// -// END: Kitchen preferences search -// - - -// -// START: Stone status screen search -// -typedef layered_search stone_search_layer; -class stone_search : public search_twocolumn_modifiable -{ - // bool in_update = false; -public: - void render() const override - { - print_search_option(21, 23); - } - - vector *get_primary_list() override - { - return &viewscreen->stone_type[viewscreen->type_tab]; - } - - vector *get_secondary_list() override - { - return &viewscreen->stone_economic[viewscreen->type_tab]; - } - - string get_element_description(int32_t stone_type) const override - { - auto iraw = vector_get(world->raws.inorganics, stone_type); - if (!iraw) - return ""; - return iraw->material.stone_name + " " + iraw->material.state_name[0]; - } - - bool should_check_input(set *input) override - { - // if (in_update) - // return false; - - if (input->count(interface_key::CHANGETAB)) - { - // Restore original list - clear_search(); - reset_all(); - } - - return true; - } - - // virtual void do_post_input_feed() override - // { - // auto *list1 = get_primary_list(); - // auto *list2 = get_secondary_list(); - // bool appended = false; - // if (list1->empty()) - // { - // // Clear uses - // auto *use_list = virtual_cast(viewscreen->layer_objects[4]); - // if (use_list) - // use_list->num_entries = 0; - // return; - // } - // else if (list1->size() == 1) - // { - // list1->push_back(list1->back()); - // list2->push_back(list2->back()); - // appended = true; - // } - - // in_update = true; - // Core::printerr("updating\n"); - // viewscreen->feed_key(interface_key::STANDARDSCROLL_DOWN); - // viewscreen->feed_key(interface_key::STANDARDSCROLL_UP); - // Core::printerr("updating done\n"); - // in_update = false; - - // if (appended) - // { - // list1->pop_back(); - // list2->pop_back(); - // } - // } -}; - -IMPLEMENT_HOOKS(df::viewscreen_layer_stone_restrictionst, stone_search); - -// -// END: Stone status screen search -// - -// -// START: Justice screen conviction search -// - -typedef search_generic justice_conviction_search_base; -class justice_conviction_search : public justice_conviction_search_base -{ -public: - bool can_init (df::viewscreen_justicest *screen) - { - return screen->cur_column == df::viewscreen_justicest::ConvictChoices; - } - - string get_element_description (df::unit *unit) const - { - return get_unit_description(unit); - } - - void render() const - { - print_search_option(37); - } - - vector *get_primary_list() - { - return &viewscreen->convict_choices; - } - - virtual int32_t *get_viewscreen_cursor() - { - return &viewscreen->cursor_right; - } -}; - -IMPLEMENT_HOOKS(df::viewscreen_justicest, justice_conviction_search); - -// -// END: Justice screen conviction search -// - -// -// START: Justice screen interrogation search -// - -typedef search_generic justice_interrogation_search_base; -class justice_interrogation_search : public justice_interrogation_search_base -{ -public: - bool can_init (df::viewscreen_justicest *screen) - { - return screen->cur_column == df::viewscreen_justicest::InterrogateChoices; - } - - string get_element_description (df::unit *unit) const - { - return get_unit_description(unit); - } - - void render() const - { - print_search_option(37); - } - - vector *get_primary_list() - { - return &viewscreen->interrogate_choices; - } - - virtual int32_t *get_viewscreen_cursor() - { - return &viewscreen->cursor_right; - } -}; - -IMPLEMENT_HOOKS(df::viewscreen_justicest, justice_interrogation_search); - -// -// END: Justice screen conviction search -// - -#define SEARCH_HOOKS \ - HOOK_ACTION(unitlist_search_hook) \ - HOOK_ACTION(roomlist_search_hook) \ - HOOK_ACTION(trade_search_merc_hook) \ - HOOK_ACTION(trade_search_fort_hook) \ - HOOK_ACTION(stocks_search_hook) \ - HOOK_ACTION(pets_search_hook) \ - HOOK_ACTION(animal_knowledge_search_hook) \ - HOOK_ACTION(animal_trainer_search_hook) \ - HOOK_ACTION(military_search_hook) \ - HOOK_ACTION(nobles_search_hook) \ - HOOK_ACTION(profiles_search_hook) \ - HOOK_ACTION(announcement_search_hook) \ - HOOK_ACTION(joblist_search_hook) \ - HOOK_ACTION(look_menu_search_hook) \ - HOOK_ACTION(burrow_search_hook) \ - HOOK_ACTION(stockpile_search_hook) \ - HOOK_ACTION(room_assign_search_hook) \ - HOOK_ACTION(noble_suggest_search_hook) \ - HOOK_ACTION(location_assign_occupation_search_hook) \ - HOOK_ACTION(kitchen_pref_search_hook) \ - HOOK_ACTION(stone_search_hook) \ - HOOK_ACTION(justice_conviction_search_hook) \ - HOOK_ACTION(justice_interrogation_search_hook) \ - - -DFhackCExport command_result plugin_enable ( color_ostream &out, bool enable) -{ - if (!gps || !gview) - return CR_FAILURE; - - if (is_enabled != enable) - { -#define HOOK_ACTION(hook) \ - !INTERPOSE_HOOK(hook, feed).apply(enable) || \ - !INTERPOSE_HOOK(hook, render).apply(enable) || \ - !INTERPOSE_HOOK(hook, key_conflict).apply(enable) || - - if (SEARCH_HOOKS 0) - return CR_FAILURE; - - is_enabled = enable; - } -#undef HOOK_ACTION - - return CR_OK; -} - -DFhackCExport command_result plugin_init ( color_ostream &out, vector &commands) -{ - return CR_OK; -} - -DFhackCExport command_result plugin_shutdown ( color_ostream &out ) -{ -#define HOOK_ACTION(hook) \ - INTERPOSE_HOOK(hook, feed).remove(); \ - INTERPOSE_HOOK(hook, render).remove(); \ - INTERPOSE_HOOK(hook, key_conflict).remove(); - - SEARCH_HOOKS - -#undef HOOK_ACTION - - return CR_OK; -} - -DFhackCExport command_result plugin_onstatechange ( color_ostream &out, state_change_event event ) -{ -#define HOOK_ACTION(hook) hook::module.reset_on_change(); - - switch (event) { - case SC_VIEWSCREEN_CHANGED: - SEARCH_HOOKS - break; - - default: - break; - } - - return CR_OK; - -#undef HOOK_ACTION -} - -#undef IMPLEMENT_HOOKS -#undef SEARCH_HOOKS