From 03e11a62e19fa2e96769ccd0f997a5d21b427fe8 Mon Sep 17 00:00:00 2001 From: Charles Dang Date: Tue, 20 Mar 2018 19:21:33 +1100 Subject: [PATCH] Removed GUI1 Help interface code Not needed anymore since we're moving to GUI2 for this dialog. --- .../project.pbxproj | 24 - source_lists/wesnoth | 3 - src/help/help.cpp | 1 - src/help/help_browser.cpp | 237 ------- src/help/help_browser.hpp | 71 --- src/help/help_menu.cpp | 210 ------- src/help/help_menu.hpp | 109 ---- src/help/help_text_area.cpp | 582 ------------------ src/help/help_text_area.hpp | 177 ------ 9 files changed, 1414 deletions(-) delete mode 100644 src/help/help_browser.cpp delete mode 100644 src/help/help_browser.hpp delete mode 100644 src/help/help_menu.cpp delete mode 100644 src/help/help_menu.hpp delete mode 100644 src/help/help_text_area.cpp delete mode 100644 src/help/help_text_area.hpp diff --git a/projectfiles/Xcode/The Battle for Wesnoth.xcodeproj/project.pbxproj b/projectfiles/Xcode/The Battle for Wesnoth.xcodeproj/project.pbxproj index a0d09799ee1..37f74743f48 100644 --- a/projectfiles/Xcode/The Battle for Wesnoth.xcodeproj/project.pbxproj +++ b/projectfiles/Xcode/The Battle for Wesnoth.xcodeproj/project.pbxproj @@ -277,12 +277,6 @@ 46F57088205FCF7E007031BF /* config_attribute_value.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EC0341DF1ECF46FE000F2E2B /* config_attribute_value.cpp */; }; 46F92C142174F5D700602C1C /* help_impl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46F92C0A2174F5D600602C1C /* help_impl.cpp */; }; 46F92C152174F5D700602C1C /* help_impl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46F92C0A2174F5D600602C1C /* help_impl.cpp */; }; - 46F92C162174F5D700602C1C /* help_browser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46F92C0B2174F5D600602C1C /* help_browser.cpp */; }; - 46F92C172174F5D700602C1C /* help_browser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46F92C0B2174F5D600602C1C /* help_browser.cpp */; }; - 46F92C182174F5D700602C1C /* help_menu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46F92C0F2174F5D700602C1C /* help_menu.cpp */; }; - 46F92C192174F5D700602C1C /* help_menu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46F92C0F2174F5D700602C1C /* help_menu.cpp */; }; - 46F92C1A2174F5D700602C1C /* help_text_area.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46F92C102174F5D700602C1C /* help_text_area.cpp */; }; - 46F92C1B2174F5D700602C1C /* help_text_area.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46F92C102174F5D700602C1C /* help_text_area.cpp */; }; 46F92C1C2174F5D700602C1C /* help_topic_generators.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46F92C112174F5D700602C1C /* help_topic_generators.cpp */; }; 46F92C1D2174F5D700602C1C /* help_topic_generators.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46F92C112174F5D700602C1C /* help_topic_generators.cpp */; }; 46F92C1E2174F5D700602C1C /* help.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46F92C132174F5D700602C1C /* help.cpp */; }; @@ -1780,14 +1774,8 @@ 46F54C26211DFB7200374A1C /* apple_version.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = apple_version.mm; path = ../../src/desktop/apple_version.mm; sourceTree = ""; }; 46F54C28211DFB9100374A1C /* apple_version.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; name = apple_version.hpp; path = ../../src/desktop/apple_version.hpp; sourceTree = ""; }; 46F92C082174F5D600602C1C /* help.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = help.hpp; sourceTree = ""; }; - 46F92C092174F5D600602C1C /* help_browser.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = help_browser.hpp; sourceTree = ""; }; 46F92C0A2174F5D600602C1C /* help_impl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = help_impl.cpp; sourceTree = ""; }; - 46F92C0B2174F5D600602C1C /* help_browser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = help_browser.cpp; sourceTree = ""; }; 46F92C0C2174F5D700602C1C /* help_impl.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = help_impl.hpp; sourceTree = ""; }; - 46F92C0D2174F5D700602C1C /* help_menu.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = help_menu.hpp; sourceTree = ""; }; - 46F92C0E2174F5D700602C1C /* help_text_area.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = help_text_area.hpp; sourceTree = ""; }; - 46F92C0F2174F5D700602C1C /* help_menu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = help_menu.cpp; sourceTree = ""; }; - 46F92C102174F5D700602C1C /* help_text_area.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = help_text_area.cpp; sourceTree = ""; }; 46F92C112174F5D700602C1C /* help_topic_generators.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = help_topic_generators.cpp; sourceTree = ""; }; 46F92C122174F5D700602C1C /* help_topic_generators.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = help_topic_generators.hpp; sourceTree = ""; }; 46F92C132174F5D700602C1C /* help.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = help.cpp; sourceTree = ""; }; @@ -4406,14 +4394,8 @@ 91B6218E1B76710700B00E0F /* help */ = { isa = PBXGroup; children = ( - 46F92C0B2174F5D600602C1C /* help_browser.cpp */, - 46F92C092174F5D600602C1C /* help_browser.hpp */, 46F92C0A2174F5D600602C1C /* help_impl.cpp */, 46F92C0C2174F5D700602C1C /* help_impl.hpp */, - 46F92C0F2174F5D700602C1C /* help_menu.cpp */, - 46F92C0D2174F5D700602C1C /* help_menu.hpp */, - 46F92C102174F5D700602C1C /* help_text_area.cpp */, - 46F92C0E2174F5D700602C1C /* help_text_area.hpp */, 46F92C112174F5D700602C1C /* help_topic_generators.cpp */, 46F92C122174F5D700602C1C /* help_topic_generators.hpp */, 46F92C132174F5D700602C1C /* help.cpp */, @@ -5549,7 +5531,6 @@ B5599B7E0EC62181008DD061 /* color_range.cpp in Sources */, ECFA82E3184E59F3006782FB /* command_executor.cpp in Sources */, 46F92E692174F6A400602C1C /* tree_view_node.cpp in Sources */, - 46F92C162174F5D700602C1C /* help_browser.cpp in Sources */, F46C5DCF13A5074C00DD0816 /* commandline_options.cpp in Sources */, 46F92DC92174F6A300602C1C /* modal_dialog.cpp in Sources */, 46F92D932174F6A300602C1C /* distributor.cpp in Sources */, @@ -5867,7 +5848,6 @@ EC64D7611A085CE60092EF75 /* seed_rng.cpp in Sources */, B5599B030EC62181008DD061 /* map_settings.cpp in Sources */, 91AF565B284D9251007A7652 /* walker_scrollbar_container.cpp in Sources */, - 46F92C1A2174F5D700602C1C /* help_text_area.cpp in Sources */, 46F92DC12174F6A300602C1C /* game_version_dialog.cpp in Sources */, ECAB84551B0C1934001A3EB7 /* shroud_clearing_action.cpp in Sources */, 46F92E892174F6A400602C1C /* matrix.cpp in Sources */, @@ -6015,7 +5995,6 @@ 9193FC7E1D5BB64F004F6C07 /* advancement.cpp in Sources */, 9193FC821D5C2CF8004F6C07 /* lua_unit.cpp in Sources */, 9193FC861D5D7461004F6C07 /* lua_unit_attacks.cpp in Sources */, - 46F92C182174F5D700602C1C /* help_menu.cpp in Sources */, 46F92E292174F6A400602C1C /* mp_join_game.cpp in Sources */, 46F92E592174F6A400602C1C /* image.cpp in Sources */, 469853CF24D3560900B0E93B /* server_info_dialog.cpp in Sources */, @@ -6351,7 +6330,6 @@ 46D60159255AFA7E00E072F0 /* commandline_argv.cpp in Sources */, 46F92F202174FEC000602C1C /* constants.cpp in Sources */, 91E356C31CACC8B800774252 /* candidates.cpp in Sources */, - 46F92C192174F5D700602C1C /* help_menu.cpp in Sources */, 91E356C41CACC8B800774252 /* engine_fai.cpp in Sources */, 91E356C51CACC8B800774252 /* function_table.cpp in Sources */, 91E356C61CACC8B800774252 /* stage_side_formulas.cpp in Sources */, @@ -6653,7 +6631,6 @@ 461DC52E241F875A00B9DD10 /* lua_color.cpp in Sources */, 91A215BB1CAD92D000927AEA /* tstring.cpp in Sources */, 91A215BF1CAD951A00927AEA /* lua_jailbreak_exception.cpp in Sources */, - 46F92C1B2174F5D700602C1C /* help_text_area.cpp in Sources */, 91A215C01CAD952C00927AEA /* game_config.cpp in Sources */, 91A215C11CAD952C00927AEA /* game_config_manager.cpp in Sources */, 91A215C21CAD954C00927AEA /* filesystem.cpp in Sources */, @@ -6701,7 +6678,6 @@ 46F92E462174F6A400602C1C /* tips.cpp in Sources */, 9107AE461DB335D5001927B0 /* paths.cpp in Sources */, 46F92DAC2174F6A300602C1C /* unit_recall.cpp in Sources */, - 46F92C172174F5D700602C1C /* help_browser.cpp in Sources */, 915C68EC1DF1DCB000594B07 /* color.cpp in Sources */, 4291489DA38012477DA3BA7C /* general.cpp in Sources */, 87744447951D17AA38BE5F48 /* mp_report.cpp in Sources */, diff --git a/source_lists/wesnoth b/source_lists/wesnoth index 914c8f0faf3..672ec0195f8 100644 --- a/source_lists/wesnoth +++ b/source_lists/wesnoth @@ -286,10 +286,7 @@ gui/widgets/widget.cpp gui/widgets/widget_helpers.cpp halo.cpp help/help.cpp -help/help_browser.cpp help/help_impl.cpp -help/help_menu.cpp -help/help_text_area.cpp help/help_topic_generators.cpp hotkey/hotkey_handler.cpp hotkey/hotkey_handler_mp.cpp diff --git a/src/help/help.cpp b/src/help/help.cpp index 51f71553706..b3dc0ef9c9c 100644 --- a/src/help/help.cpp +++ b/src/help/help.cpp @@ -30,7 +30,6 @@ #include "gettext.hpp" // for _ #include "gui/dialogs/help_browser.hpp" #include "gui/widgets/settings.hpp" -#include "help/help_browser.hpp" // for help_browser #include "help/help_impl.hpp" // for hidden_symbol, toplevel, etc #include "key.hpp" // for CKey #include "log.hpp" // for LOG_STREAM, log_domain diff --git a/src/help/help_browser.cpp b/src/help/help_browser.cpp deleted file mode 100644 index 2f184f51291..00000000000 --- a/src/help/help_browser.cpp +++ /dev/null @@ -1,237 +0,0 @@ -/* - Copyright (C) 2003 - 2024 - by David White - Part of the Battle for Wesnoth Project https://www.wesnoth.org/ - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY. - - See the COPYING file for more details. -*/ - -#include "help/help_browser.hpp" -#include "cursor.hpp" // for set, CURSOR_TYPE::HYPERLINK, etc -#include "font/constants.hpp" // for relative_size -#include "help/help_text_area.hpp" // for help_text_area -#include "help/help_impl.hpp" // for find_topic, hidden_symbol, etc -#include "key.hpp" // for CKey -#include "log.hpp" // for log_scope -#include "sdl/rect.hpp" -#include "sdl/input.hpp" // for get_mouse_state - - -namespace help { - -help_browser::help_browser(const section &toplevel) : - gui::widget(), - menu_(toplevel), - text_area_(toplevel), toplevel_(toplevel), - ref_cursor_(false), - back_topics_(), - forward_topics_(), - back_button_("", gui::button::TYPE_PRESS, "button_normal/button_small_H22", gui::button::DEFAULT_SPACE, true, "icons/arrows/long_arrow_ornate_left"), - forward_button_("", gui::button::TYPE_PRESS, "button_normal/button_small_H22", gui::button::DEFAULT_SPACE, true, "icons/arrows/long_arrow_ornate_right"), - shown_topic_(nullptr) -{ - // Hide the buttons at first since we do not have any forward or - // back topics at this point. They will be unhidden when history - // appears. - back_button_.hide(true); - forward_button_.hide(true); - // Set sizes to some default values. - set_measurements(font::relative_size(400), font::relative_size(500)); -} - -void help_browser::adjust_layout() -{ - const int menu_buttons_padding = font::relative_size(10); - const int menu_y = location().y; - const int menu_x = location().x; - const int menu_w = 250; - const int menu_h = height(); - - const int menu_text_area_padding = font::relative_size(10); - const int text_area_y = location().y; - const int text_area_x = menu_x + menu_w + menu_text_area_padding; - const int text_area_w = width() - menu_w - menu_text_area_padding; - const int text_area_h = height(); - - const int button_border_padding = 0; - const int button_button_padding = font::relative_size(10); - const int back_button_x = location().x + button_border_padding; - const int back_button_y = menu_y + menu_h + menu_buttons_padding; - const int forward_button_x = back_button_x + back_button_.width() + button_button_padding; - const int forward_button_y = back_button_y; - - menu_.set_width(menu_w); - menu_.set_location(menu_x, menu_y); - menu_.set_max_height(menu_h); - menu_.set_max_width(menu_w); - - text_area_.set_location(text_area_x, text_area_y); - text_area_.set_width(text_area_w); - text_area_.set_height(text_area_h); - - back_button_.set_location(back_button_x, back_button_y); - forward_button_.set_location(forward_button_x, forward_button_y); - - queue_redraw(); -} - -void help_browser::update_location(const SDL_Rect&) -{ - adjust_layout(); -} - -void help_browser::process_event() -{ - CKey key; - int mousex, mousey; - sdl::get_mouse_state(&mousex,&mousey); - - // Fake focus functionality for the menu, only process it if it has focus. - if (menu_.location().contains(mousex, mousey)) { - menu_.process(); - const topic *chosen_topic = menu_.chosen_topic(); - if (chosen_topic != nullptr && chosen_topic != shown_topic_) { - // A new topic has been chosen in the menu, display it. - show_topic(*chosen_topic); - } - } - if (back_button_.pressed()) { - move_in_history(back_topics_, forward_topics_); - } - if (forward_button_.pressed()) { - move_in_history(forward_topics_, back_topics_); - } - back_button_.hide(back_topics_.empty()); - forward_button_.hide(forward_topics_.empty()); -} - -void help_browser::move_in_history(std::deque &from, - std::deque &to) -{ - if (!from.empty()) { - const topic *to_show = from.back(); - from.pop_back(); - if (shown_topic_ != nullptr) { - if (to.size() > max_history) { - to.pop_front(); - } - to.push_back(shown_topic_); - } - show_topic(*to_show, false); - } -} - - -void help_browser::handle_event(const SDL_Event &event) -{ - gui::widget::handle_event(event); - - SDL_MouseButtonEvent mouse_event = event.button; - if (event.type == SDL_MOUSEBUTTONDOWN) { - if (mouse_event.button == SDL_BUTTON_LEFT) { - // Did the user click a cross-reference? - const int mousex = mouse_event.x; - const int mousey = mouse_event.y; - const std::string ref = text_area_.ref_at(mousex, mousey); - if (!ref.empty()) { - const topic *t = find_topic(toplevel_, ref); - if (t == nullptr) { - // - // HACK: there are difficult-to-solve issues with a GUI2 popup over the - // GUI1 help browser (see issue #2587). Simply disabling it for now. - // Should be reenabled once the help browser switches to GUI2. - // - // -- vultraz, 2018-03-05 - // -#if 0 - std::stringstream msg; - msg << _("Reference to unknown topic: ") << "'" << ref << "'."; - gui2::show_transient_message("", msg.str()); -#endif - update_cursor(); - } - else { - show_topic(*t); - update_cursor(); - } - } - } - else { - const bool mouse_back = !back_button_.hidden() && mouse_event.button == SDL_BUTTON_X1; - const bool mouse_forward = !forward_button_.hidden() && mouse_event.button == SDL_BUTTON_X2; - - if (mouse_back) { - move_in_history(back_topics_, forward_topics_); - } - if (mouse_forward) { - move_in_history(forward_topics_, back_topics_); - } - if (mouse_back || mouse_forward) { - back_button_.hide(back_topics_.empty()); - forward_button_.hide(forward_topics_.empty()); - } - } - } - else if (event.type == SDL_MOUSEMOTION) { - update_cursor(); - } -} - -void help_browser::update_cursor() -{ - int mousex, mousey; - sdl::get_mouse_state(&mousex,&mousey); - const std::string ref = text_area_.ref_at(mousex, mousey); - if (!ref.empty() && !ref_cursor_) { - cursor::set(cursor::HYPERLINK); - ref_cursor_ = true; - } - else if (ref.empty() && ref_cursor_) { - cursor::set(cursor::NORMAL); - ref_cursor_ = false; - } -} - -void help_browser::show_topic(const std::string &topic_id) -{ - const topic *t = find_topic(toplevel_, topic_id); - - if (t != nullptr) { - show_topic(*t); - } else if (topic_id.find(unit_prefix)==0 || topic_id.find(hidden_symbol() + unit_prefix)==0) { - show_topic(unknown_unit_topic); - } else { - PLAIN_LOG << "Help browser tried to show topic with id '" << topic_id - << "' but that topic could not be found." << std::endl; - } -} - -void help_browser::show_topic(const topic &t, bool save_in_history) -{ - log_scope("show_topic"); - - if (save_in_history) { - forward_topics_.clear(); - if (shown_topic_ != nullptr) { - if (back_topics_.size() > max_history) { - back_topics_.pop_front(); - } - back_topics_.push_back(shown_topic_); - } - } - - shown_topic_ = &t; - text_area_.show_topic(t); - menu_.select_topic(t); - update_cursor(); -} - - -} // end namespace help diff --git a/src/help/help_browser.hpp b/src/help/help_browser.hpp deleted file mode 100644 index 3a40333712d..00000000000 --- a/src/help/help_browser.hpp +++ /dev/null @@ -1,71 +0,0 @@ -/* - Copyright (C) 2003 - 2024 - by David White - Part of the Battle for Wesnoth Project https://www.wesnoth.org/ - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY. - - See the COPYING file for more details. -*/ - -#pragma once - -#include // for deque -#include // for string -#include // for SDL_Event -#include "help_menu.hpp" // for help_menu -#include "help_text_area.hpp" // for help_text_area -#include "widgets/button.hpp" // for button -#include "widgets/widget.hpp" // for widget - - -namespace help { - -/** A help browser widget. */ -class help_browser : public gui::widget -{ -public: - help_browser(const section &toplevel); - - void adjust_layout(); - - /** - * Display the topic with the specified identifier. Open the menu - * on the right location and display the topic in the text area. - */ - void show_topic(const std::string &topic_id); - -protected: - virtual void update_location(const SDL_Rect& rect); - virtual void process_event(); - virtual void handle_event(const SDL_Event &event); - -private: - /** - * Update the current cursor, set it to the reference cursor if - * mousex, mousey is over a cross-reference, otherwise, set it to - * the normal cursor. - */ - void update_cursor(); - void show_topic(const topic &t, bool save_in_history=true); - /** - * Move in the topic history. Pop an element from from and insert - * it in to. Pop at the fronts if the maximum number of elements is - * exceeded. - */ - void move_in_history(std::deque &from, std::deque &to); - help_menu menu_; - help_text_area text_area_; - const section &toplevel_; - bool ref_cursor_; // If the cursor currently is the hyperlink cursor. - std::deque back_topics_, forward_topics_; - gui::button back_button_, forward_button_; - topic const *shown_topic_; -}; - -} // end namespace help diff --git a/src/help/help_menu.cpp b/src/help/help_menu.cpp deleted file mode 100644 index 6a98ebfde30..00000000000 --- a/src/help/help_menu.cpp +++ /dev/null @@ -1,210 +0,0 @@ -/* - Copyright (C) 2003 - 2024 - by David White - Part of the Battle for Wesnoth Project https://www.wesnoth.org/ - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY. - - See the COPYING file for more details. -*/ - -#include "help/help_menu.hpp" - -#include "game_config.hpp" // for menu_contract, menu_expand -#include "help/help_impl.hpp" // for section, topic, topic_list, etc -#include "sound.hpp" // for play_UI_sound -#include "sdl/input.hpp" // for get_mouse_state - -#include // for find -#include // for _List_const_iterator, etc -#include // for pair - -namespace help { - -help_menu::help_menu(const section& toplevel, int max_height) : - gui::menu(true, max_height, -1, &gui::menu::bluebg_style), - visible_items_(), - toplevel_(toplevel), - expanded_(), - chosen_topic_(nullptr), - selected_item_(&toplevel, 0) -{ - silent_ = true; //silence the default menu sounds - update_visible_items(toplevel_); - display_visible_items(); - if (!visible_items_.empty()) - selected_item_ = visible_items_.front(); -} - -bool help_menu::expanded(const section &sec) const -{ - return expanded_.find(&sec) != expanded_.end(); -} - -void help_menu::expand(const section &sec) -{ - if (sec.id != "toplevel" && expanded_.insert(&sec).second) { - sound::play_UI_sound(game_config::sounds::menu_expand); - } -} - -void help_menu::contract(const section &sec) -{ - if (expanded_.erase(&sec)) { - sound::play_UI_sound(game_config::sounds::menu_contract); - } -} - -void help_menu::update_visible_items(const section &sec, unsigned level) -{ - if (level == 0) { - // Clear if this is the top level, otherwise append items. - visible_items_.clear(); - } - for (const auto &s : sec.sections) { - if (is_visible_id(s.id)) { - visible_items_.emplace_back(&s, level + 1); - if (expanded(s)) { - update_visible_items(s, level + 1); - } - } - } - for (const auto &t : sec.topics) { - if (is_visible_id(t.id)) { - visible_items_.emplace_back(&t, level + 1); - } - } -} - -bool help_menu::select_topic_internal(const topic &t, const section &sec) -{ - topic_list::const_iterator tit = - std::find(sec.topics.begin(), sec.topics.end(), t); - if (tit != sec.topics.end()) { - // topic starting with ".." are assumed as rooted in the parent section - // and so only expand the parent when selected - if (t.id.size()<2 || t.id[0] != '.' || t.id[1] != '.') - expand(sec); - return true; - } - for (const auto &s : sec.sections) { - if (select_topic_internal(t, s)) { - expand(sec); - return true; - } - } - return false; -} - -void help_menu::select_topic(const topic &t) -{ - if (selected_item_ == t) { - // The requested topic is already selected. - return; - } - if (select_topic_internal(t, toplevel_)) { - update_visible_items(toplevel_); - for (std::vector::const_iterator it = visible_items_.begin(); - it != visible_items_.end(); ++it) { - if (*it == t) { - selected_item_ = *it; - break; - } - } - display_visible_items(); - } -} - -int help_menu::process() -{ - int res = menu::process(); - int mousex, mousey; - sdl::get_mouse_state(&mousex, &mousey); - - if (!visible_items_.empty() - && static_cast(res) < visible_items_.size()) - { - selected_item_ = visible_items_[res]; - const section* sec = selected_item_.sec; - if (sec != nullptr) { - // Behavior of the UI, for section headings: - // * user single-clicks on the text part: show the ".." topic in the right-hand pane - // * user single-clicks on the icon (or to the left of it): expand or collapse the tree view - // * user double-clicks anywhere: expand or collapse the tree view - // * note: the first click of the double-click has the single-click effect too - if (menu::double_clicked() || hit_on_indent_or_icon(static_cast(res), mousex)) { - // Open or close a section if we double-click on it - // or do simple click on the icon. - expanded(*sec) ? contract(*sec) : expand(*sec); - update_visible_items(toplevel_); - display_visible_items(); - } else { - // click on title open the topic associated to this section - chosen_topic_ = find_topic(default_toplevel, ".."+sec->id ); - } - } else if (selected_item_.t != nullptr) { - // Choose a topic if it is clicked. - chosen_topic_ = selected_item_.t; - } - } - return res; -} - -const topic *help_menu::chosen_topic() -{ - const topic *ret = chosen_topic_; - chosen_topic_ = nullptr; - return ret; -} - -void help_menu::display_visible_items() -{ - std::vector menu_items; - utils::optional selected; - for(std::vector::const_iterator items_it = visible_items_.begin(), - end = visible_items_.end(); items_it != end; ++items_it) { - if (selected_item_ == *items_it) - selected = menu_items.size(); - menu_items.push_back(items_it->get_menu_item(*this)); - } - set_items(menu_items, selected); -} - -help_menu::visible_item::visible_item(const section *_sec, int lev) : - t(nullptr), sec(_sec), level(lev) {} - -help_menu::visible_item::visible_item(const topic *_t, int lev) : - t(_t), sec(nullptr), level(lev) {} - -gui::indented_menu_item help_menu::visible_item::get_menu_item(const help_menu& parent) const -{ - if(sec) { - const auto& img = parent.expanded(*sec) ? open_section_img : closed_section_img; - return {level, img, sec->title}; - } - - // As sec was a nullptr, this must have a non-null topic - return {level, topic_img, t->title}; -} - -bool help_menu::visible_item::operator==(const section &_sec) const -{ - return sec != nullptr && *sec == _sec; -} - -bool help_menu::visible_item::operator==(const topic &_t) const -{ - return t != nullptr && *t == _t; -} - -bool help_menu::visible_item::operator==(const visible_item &vis_item) const -{ - return t == vis_item.t && sec == vis_item.sec; -} - -} // end namespace help diff --git a/src/help/help_menu.hpp b/src/help/help_menu.hpp deleted file mode 100644 index b43fb8bdda3..00000000000 --- a/src/help/help_menu.hpp +++ /dev/null @@ -1,109 +0,0 @@ -/* - Copyright (C) 2003 - 2024 - by David White - Part of the Battle for Wesnoth Project https://www.wesnoth.org/ - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY. - - See the COPYING file for more details. -*/ - -#pragma once - -#include // for set -#include // for string, basic_string -#include // for vector -#include "widgets/menu.hpp" // for menu - -namespace help { struct section; } -namespace help { struct topic; } - -namespace help { - -/** - * The menu to the left in the help browser, where topics can be - * navigated through and chosen. - */ -class help_menu : public gui::menu -{ -public: - help_menu(const section &toplevel, int max_height=-1); - int process(); - - /** - * Make the topic the currently selected one, and expand all - * sections that need to be expanded to show it. - */ - void select_topic(const topic &t); - - /** - * If a topic has been chosen, return that topic, otherwise - * nullptr. If one topic is returned, it will not be returned again, - * if it is not re-chosen. - */ - const topic *chosen_topic(); - -private: - /** Information about an item that is visible in the menu. */ - struct visible_item { - visible_item(const section *_sec, int level); - visible_item(const topic *_t, int level); - // Invariant, one if these should be nullptr. The constructors - // enforce it. - const topic *t; - const section *sec; - gui::indented_menu_item get_menu_item(const help_menu& parent) const; - /** Indentation level, always one more than the parent section. */ - int level; - bool operator==(const visible_item &sec) const; - bool operator==(const section &sec) const; - bool operator==(const topic &t) const; - }; - - /** Regenerate what items are visible by checking what sections are expanded. */ - void update_visible_items(const section &top_level, unsigned starting_level=0); - - /** Return true if the section is expanded. */ - bool expanded(const section &sec) const; - - /** Mark a section as expanded. Do not update the visible items or anything. */ - void expand(const section &sec); - - /** - * Contract (close) a section. That is, mark it as not expanded, - * visible items are not updated. - */ - void contract(const section &sec); - - /** - * Return the string to use as the prefix for the icon part of the - * menu-string at the specified level. - */ - std::string indent_list(const std::string &icon, const unsigned level); - /** Return the data to use with the superclass's set_items() for sections at the specified level. */ - gui::indented_menu_item get_item_to_show(const section &sec, const unsigned level); - /** Return the data to use with the superclass's set_items() for topics at the specified level. */ - gui::indented_menu_item get_item_to_show(const topic &topic, const unsigned level); - - /** Draw the currently visible items. */ - void display_visible_items(); - - /** - * Internal recursive thingie. did_expand will be true if any - * section was expanded, otherwise untouched. - */ - bool select_topic_internal(const topic &t, const section &sec); - - std::vector visible_items_; - const section &toplevel_; - std::set expanded_; - topic const *chosen_topic_; - visible_item selected_item_; -}; - -} // end namespace help diff --git a/src/help/help_text_area.cpp b/src/help/help_text_area.cpp deleted file mode 100644 index 6ca0ad581f1..00000000000 --- a/src/help/help_text_area.cpp +++ /dev/null @@ -1,582 +0,0 @@ -/* - Copyright (C) 2003 - 2024 - by David White - Part of the Battle for Wesnoth Project https://www.wesnoth.org/ - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY. - - See the COPYING file for more details. -*/ - -#include "help/help_text_area.hpp" - -#include "config.hpp" // for config, etc -#include "draw.hpp" // for blit, fill -#include "font/sdl_ttf_compat.hpp" -#include "font/standard_colors.hpp" // for string_to_color -#include "game_config.hpp" // for debug -#include "help/help_impl.hpp" // for parse_error, box_width, etc -#include "lexical_cast.hpp" -#include "log.hpp" // for LOG_STREAM, log_domain, etc -#include "picture.hpp" // for get_image -#include "preferences/preferences.hpp" // for font_scaled -#include "sdl/rect.hpp" // for draw_rectangle, etc -#include "sdl/texture.hpp" // for texture -#include "serialization/parser.hpp" // for read, write - -#include // for max, min, find_if -#include // for vector, etc - -static lg::log_domain log_display("display"); -#define WRN_DP LOG_STREAM(warn, log_display) - -static lg::log_domain log_help("help"); -#define ERR_HP LOG_STREAM(err, log_help) -#define WRN_HP LOG_STREAM(warn, log_help) -#define DBG_HP LOG_STREAM(debug, log_help) - -namespace help { - -help_text_area::help_text_area(const section &toplevel) : - gui::scrollarea(), - items_(), - last_row_(), - toplevel_(toplevel), - shown_topic_(nullptr), - title_spacing_(16), - curr_loc_(0, 0), - min_row_height_(4 + font::get_max_height(normal_font_size)), - curr_row_height_(min_row_height_), - contents_height_(0) -{ - set_scroll_rate(40); -} - -void help_text_area::set_inner_location(const SDL_Rect& /*rect*/) -{ - if (shown_topic_) - set_items(); -} - -void help_text_area::show_topic(const topic &t) -{ - shown_topic_ = &t; - set_items(); - queue_redraw(); - DBG_HP << "Showing topic: " << t.id << ": " << t.title; -} - - -help_text_area::item::item(const texture& _tex, int x, int y, const std::string& _text, - const std::string& reference_to, bool _floating, - bool _box, ALIGNMENT alignment) : - rect_(), - tex(_tex), - text(_text), - ref_to(reference_to), - floating(_floating), box(_box), - align(alignment) -{ - rect_.x = x; - rect_.y = y; - rect_.w = box ? tex.w() + box_width * 2 : tex.w(); - rect_.h = box ? tex.h() + box_width * 2 : tex.h(); -} - -help_text_area::item::item(const texture& _tex, int x, int y, bool _floating, - bool _box, ALIGNMENT alignment) : - rect_(), - tex(_tex), - text(""), - ref_to(""), - floating(_floating), - box(_box), align(alignment) -{ - rect_.x = x; - rect_.y = y; - rect_.w = box ? tex.w() + box_width * 2 : tex.w(); - rect_.h = box ? tex.h() + box_width * 2 : tex.h(); -} - -void help_text_area::set_items() -{ - last_row_.clear(); - items_.clear(); - curr_loc_.first = 0; - curr_loc_.second = 0; - curr_row_height_ = min_row_height_; - // Add the title item. - const std::string show_title = font::pango_line_ellipsize( - shown_topic_->title, title_size, inner_location().w); - texture tex(font::pango_render_text(show_title, title_size, - font::NORMAL_COLOR, font::pango_text::STYLE_BOLD)); - if (tex) { - add_item(item(tex, 0, 0, show_title)); - curr_loc_.second = title_spacing_; - contents_height_ = title_spacing_; - down_one_line(); - } - // Parse and add the text. - const config& parsed_items = shown_topic_->text.parsed_text(); - for(auto item : parsed_items.all_children_range()) { -#define TRY(name) do { \ - if (item.key == #name) \ - handle_##name##_cfg(item.cfg); \ - } while (0) - - TRY(text); - TRY(ref); - TRY(img); - TRY(bold); - TRY(italic); - TRY(header); - TRY(jump); - TRY(format); -#undef TRY - } - down_one_line(); // End the last line. - int h = height(); - set_position(0); - set_full_size(contents_height_); - set_shown_size(h); -} - -void help_text_area::handle_ref_cfg(const config &cfg) -{ - const std::string dst = cfg["dst"]; - const std::string text = cfg["text"]; - bool force = cfg["force"].to_bool(); - - if (dst.empty()) { - std::stringstream msg; - msg << "Ref markup must have dst attribute. Please submit a bug" - " report if you have not modified the game files yourself. Erroneous config: "; - write(msg, cfg); - throw parse_error(msg.str()); - } - - if (find_topic(toplevel_, dst) == nullptr && !force) { - // detect the broken link but quietly silence the hyperlink for normal user - add_text_item(text, game_config::debug ? dst : "", true); - - // FIXME: workaround: if different campaigns define different - // terrains, some terrains available in one campaign will - // appear in the list of seen terrains, and be displayed in the - // help, even if the current campaign does not handle such - // terrains. This will lead to the unit page generator creating - // invalid references. - // - // Disabling this is a kludgey workaround until the - // encountered_terrains system is fixed - // - // -- Ayin apr 8 2005 -#if 0 - if (game_config::debug) { - std::stringstream msg; - msg << "Reference to non-existent topic '" << dst - << "'. Please submit a bug report if you have not" - "modified the game files yourself. Erroneous config: "; - write(msg, cfg); - throw parse_error(msg.str()); - } -#endif - } else { - add_text_item(text, dst); - } -} - -void help_text_area::handle_img_cfg(const config &cfg) -{ - const std::string src = cfg["src"]; - const std::string align = cfg["align"]; - bool floating = cfg["float"].to_bool(); - bool box = cfg["box"].to_bool(true); - if (src.empty()) { - throw parse_error("Img markup must have src attribute."); - } - add_img_item(src, align, floating, box); -} - -void help_text_area::handle_bold_cfg(const config &cfg) -{ - const std::string text = cfg["text"]; - if (text.empty()) { - throw parse_error("Bold markup must have text attribute."); - } - add_text_item(text, "", false, -1, true); -} - -void help_text_area::handle_italic_cfg(const config &cfg) -{ - const std::string text = cfg["text"]; - if (text.empty()) { - throw parse_error("Italic markup must have text attribute."); - } - add_text_item(text, "", false, -1, false, true); -} - -void help_text_area::handle_header_cfg(const config &cfg) -{ - const std::string text = cfg["text"]; - if (text.empty()) { - throw parse_error("Header markup must have text attribute."); - } - add_text_item(text, "", false, title2_size, true); -} - -void help_text_area::handle_jump_cfg(const config &cfg) -{ - const std::string amount_str = cfg["amount"]; - const std::string to_str = cfg["to"]; - if (amount_str.empty() && to_str.empty()) { - throw parse_error("Jump markup must have either a to or an amount attribute."); - } - unsigned jump_to = curr_loc_.first; - if (!amount_str.empty()) { - unsigned amount; - try { - amount = lexical_cast(amount_str); - } - catch (bad_lexical_cast&) { - throw parse_error("Invalid amount the amount attribute in jump markup."); - } - jump_to += amount; - } - if (!to_str.empty()) { - unsigned to; - try { - to = lexical_cast(to_str); - } - catch (bad_lexical_cast&) { - throw parse_error("Invalid amount in the to attribute in jump markup."); - } - if (to < jump_to) { - down_one_line(); - } - jump_to = to; - } - if (jump_to != 0 && static_cast(jump_to) < - get_max_x(curr_loc_.first, curr_row_height_)) { - - curr_loc_.first = jump_to; - } -} - -void help_text_area::handle_format_cfg(const config &cfg) -{ - const std::string text = cfg["text"]; - if (text.empty()) { - throw parse_error("Format markup must have text attribute."); - } - bool bold = cfg["bold"].to_bool(); - bool italic = cfg["italic"].to_bool(); - int font_size = cfg["font_size"].to_int(normal_font_size); - color_t color = font::string_to_color(cfg["color"]); - add_text_item(text, "", false, font_size, bold, italic, color); -} - -void help_text_area::handle_text_cfg(const config& cfg) { - add_text_item(cfg["text"]); -} - -void help_text_area::add_text_item(const std::string& text, const std::string& ref_dst, - bool broken_link, int _font_size, bool bold, bool italic, - color_t text_color -) -{ - const int font_size = _font_size < 0 ? normal_font_size : _font_size; - // font::line_width(), font::get_rendered_text() are not use scaled font inside - const int scaled_font_size = prefs::get().font_scaled(font_size); - if (text.empty()) - return; - const int remaining_width = get_remaining_width(); - std::size_t first_word_start = text.find_first_not_of(" "); - if (first_word_start == std::string::npos) { - first_word_start = 0; - } - if (text[first_word_start] == '\n') { - down_one_line(); - std::string rest_text = text; - rest_text.erase(0, first_word_start + 1); - add_text_item(rest_text, ref_dst, broken_link, _font_size, bold, italic, text_color); - return; - } - const std::string first_word = get_first_word(text); - int state = font::pango_text::STYLE_NORMAL; - state |= bold ? font::pango_text::STYLE_BOLD : 0; - state |= italic ? font::pango_text::STYLE_ITALIC : 0; - if (curr_loc_.first != get_min_x(curr_loc_.second, curr_row_height_) - && remaining_width < font::pango_line_width(first_word, scaled_font_size, font::pango_text::FONT_STYLE(state))) { - // The first word does not fit, and we are not at the start of - // the line. Move down. - down_one_line(); - std::string s = remove_first_space(text); - add_text_item(s, ref_dst, broken_link, _font_size, bold, italic, text_color); - } - else { - std::vector parts = split_in_width(text, font_size, remaining_width); - std::string first_part = parts.front(); - // Always override the color if we have a cross reference. - color_t color; - if(ref_dst.empty()) - color = text_color; - else if(broken_link) - color = font::BAD_COLOR; - else - color = font::YELLOW_COLOR; - - // In split_in_width(), no_break_after() and no_break_before() are used(see marked-up_text.cpp). - // Thus, even if there is enough remaining_width for the next word, - // sometimes empty string is returned from split_in_width(). - if (first_part.empty()) { - down_one_line(); - } - else { - texture tex(font::pango_render_text(first_part, - scaled_font_size, color, font::pango_text::FONT_STYLE(state))); - if (tex) { - add_item(item(tex, curr_loc_.first, curr_loc_.second, - first_part, ref_dst)); - } - } - if (parts.size() > 1) { - - std::string& s = parts.back(); - - const std::string first_word_before = get_first_word(s); - const std::string first_word_after = get_first_word(remove_first_space(s)); - if (get_remaining_width() >= font::pango_line_width(first_word_after, scaled_font_size, font::pango_text::FONT_STYLE(state)) - && get_remaining_width() - < font::pango_line_width(first_word_before, scaled_font_size, font::pango_text::FONT_STYLE(state))) { - // If the removal of the space made this word fit, we - // must move down a line, otherwise it will be drawn - // without a space at the end of the line. - s = remove_first_space(s); - down_one_line(); - } - else if (!(font::pango_line_width(first_word_before, scaled_font_size, font::pango_text::FONT_STYLE(state)) - < get_remaining_width())) { - s = remove_first_space(s); - } - add_text_item(s, ref_dst, broken_link, _font_size, bold, italic, text_color); - - } - } -} - -void help_text_area::add_img_item(const std::string& path, const std::string& alignment, - const bool floating, const bool box) -{ - texture tex(image::get_texture(path)); - if (!tex) - return; - ALIGNMENT align = str_to_align(alignment); - if (align == HERE && floating) { - WRN_DP << "Floating image with align HERE, aligning left."; - align = LEFT; - } - const int width = tex.w() + (box ? box_width * 2 : 0); - int xpos; - int ypos = curr_loc_.second; - int text_width = inner_location().w; - switch (align) { - case HERE: - xpos = curr_loc_.first; - break; - case LEFT: - default: - xpos = 0; - break; - case MIDDLE: - xpos = text_width / 2 - width / 2 - (box ? box_width : 0); - break; - case RIGHT: - xpos = text_width - width - (box ? box_width * 2 : 0); - break; - } - if (curr_loc_.first != get_min_x(curr_loc_.second, curr_row_height_) - && (xpos < curr_loc_.first || xpos + width > text_width)) { - down_one_line(); - add_img_item(path, alignment, floating, box); - } - else { - if (!floating) { - curr_loc_.first = xpos; - } - else { - ypos = get_y_for_floating_img(width, xpos, ypos); - } - add_item(item(tex, xpos, ypos, floating, box, align)); - } -} - -int help_text_area::get_y_for_floating_img(const int width, const int x, const int desired_y) -{ - int min_y = desired_y; - for (std::list::const_iterator it = items_.begin(); it != items_.end(); ++it) { - const item& itm = *it; - if (itm.floating) { - if ((itm.rect_.x + itm.rect_.w > x && itm.rect_.x < x + width) - || (itm.rect_.x > x && itm.rect_.x < x + width)) { - min_y = std::max(min_y, itm.rect_.y + itm.rect_.h); - } - } - } - return min_y; -} - -int help_text_area::get_min_x(const int y, const int height) -{ - int min_x = 0; - for (std::list::const_iterator it = items_.begin(); it != items_.end(); ++it) { - const item& itm = *it; - if (itm.floating) { - if (itm.rect_.y < y + height && itm.rect_.y + itm.rect_.h > y && itm.align == LEFT) { - min_x = std::max(min_x, itm.rect_.w + 5); - } - } - } - return min_x; -} - -int help_text_area::get_max_x(const int y, const int height) -{ - int text_width = inner_location().w; - int max_x = text_width; - for (std::list::const_iterator it = items_.begin(); it != items_.end(); ++it) { - const item& itm = *it; - if (itm.floating) { - if (itm.rect_.y < y + height && itm.rect_.y + itm.rect_.h > y) { - if (itm.align == RIGHT) { - max_x = std::min(max_x, text_width - itm.rect_.w - 5); - } else if (itm.align == MIDDLE) { - max_x = std::min(max_x, text_width / 2 - itm.rect_.w / 2 - 5); - } - } - } - } - return max_x; -} - -void help_text_area::add_item(const item &itm) -{ - items_.push_back(itm); - if (!itm.floating) { - curr_loc_.first += itm.rect_.w; - curr_row_height_ = std::max(itm.rect_.h, curr_row_height_); - contents_height_ = std::max(contents_height_, curr_loc_.second + curr_row_height_); - last_row_.push_back(&items_.back()); - } - else { - if (itm.align == LEFT) { - curr_loc_.first = itm.rect_.w + 5; - } - contents_height_ = std::max(contents_height_, itm.rect_.y + itm.rect_.h); - } -} - - -help_text_area::ALIGNMENT help_text_area::str_to_align(const std::string &cmp_str) -{ - if (cmp_str == "left") { - return LEFT; - } else if (cmp_str == "middle") { - return MIDDLE; - } else if (cmp_str == "right") { - return RIGHT; - } else if (cmp_str == "here" || cmp_str.empty()) { // Make the empty string be "here" alignment. - return HERE; - } - std::stringstream msg; - msg << "Invalid alignment string: '" << cmp_str << "'"; - throw parse_error(msg.str()); -} - -void help_text_area::down_one_line() -{ - adjust_last_row(); - last_row_.clear(); - curr_loc_.second += curr_row_height_ + (curr_row_height_ == min_row_height_ ? 0 : 2); - curr_row_height_ = min_row_height_; - contents_height_ = std::max(curr_loc_.second + curr_row_height_, contents_height_); - curr_loc_.first = get_min_x(curr_loc_.second, curr_row_height_); -} - -void help_text_area::adjust_last_row() -{ - for (std::list::iterator it = last_row_.begin(); it != last_row_.end(); ++it) { - item &itm = *(*it); - const int gap = curr_row_height_ - itm.rect_.h; - itm.rect_.y += gap / 2; - } -} - -int help_text_area::get_remaining_width() -{ - const int total_w = get_max_x(curr_loc_.second, curr_row_height_); - return total_w - curr_loc_.first; -} - -void help_text_area::draw_contents() -{ - const SDL_Rect& loc = inner_location(); - auto clipper = draw::reduce_clip(loc); - for(std::list::const_iterator it = items_.begin(), end = items_.end(); it != end; ++it) { - SDL_Rect dst = it->rect_; - dst.y -= get_position(); - if (dst.y < static_cast(loc.h) && dst.y + it->rect_.h > 0) { - dst.x += loc.x; - dst.y += loc.y; - if (it->box) { - for (int i = 0; i < box_width; ++i) { - SDL_Rect draw_rect { - dst.x, - dst.y, - it->rect_.w - i * 2, - it->rect_.h - i * 2 - }; - draw::fill(draw_rect, 0, 0, 0, 0); - ++dst.x; - ++dst.y; - } - } - draw::blit(it->tex, dst); - } - } -} - -void help_text_area::scroll(unsigned int) -{ - // Nothing will be done on the actual scroll event. The scroll - // position is checked when drawing instead and things drawn - // accordingly. - queue_redraw(); -} - -bool help_text_area::item_at::operator()(const item& item) const { - return item.rect_.contains(x_, y_); -} - -std::string help_text_area::ref_at(const int x, const int y) -{ - const int local_x = x - location().x; - const int local_y = y - location().y; - if (local_y < height() && local_y > 0) { - const int cmp_y = local_y + get_position(); - const std::list::const_iterator it = - std::find_if(items_.begin(), items_.end(), item_at(local_x, cmp_y)); - if (it != items_.end()) { - if (!(*it).ref_to.empty()) { - return ((*it).ref_to); - } - } - } - return ""; -} - -} // end namespace help diff --git a/src/help/help_text_area.hpp b/src/help/help_text_area.hpp deleted file mode 100644 index b78692e4ec0..00000000000 --- a/src/help/help_text_area.hpp +++ /dev/null @@ -1,177 +0,0 @@ -/* - Copyright (C) 2003 - 2024 - by David White - Part of the Battle for Wesnoth Project https://www.wesnoth.org/ - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY. - - See the COPYING file for more details. -*/ - -#pragma once - -#include // for list -#include // for string -#include // for pair -#include "font/standard_colors.hpp" // for NORMAL_COLOR -#include "sdl/texture.hpp" // for texture -#include "widgets/scrollarea.hpp" // for scrollarea - -class config; -namespace help { struct section; } -namespace help { struct topic; } - -namespace help { - - -/** The area where the content is shown in the help browser. */ -class help_text_area : public gui::scrollarea -{ -public: - help_text_area(const section &toplevel); - /** Display the topic. */ - void show_topic(const topic &t); - - /** - * Return the ID that is cross-referenced at the (screen) - * coordinates x, y. If no cross-reference is there, return the - * empty string. - */ - std::string ref_at(const int x, const int y); - -protected: - virtual void scroll(unsigned int pos); - virtual void set_inner_location(const SDL_Rect& rect); - -private: - enum ALIGNMENT {LEFT, MIDDLE, RIGHT, HERE}; - /** Convert a string to an alignment. Throw parse_error if unsuccessful. */ - ALIGNMENT str_to_align(const std::string &s); - - /** - * An item that is displayed in the text area. Contains the surface - * that should be blitted along with some other information. - */ - struct item { - - item(const texture& tex, int x, int y, const std::string& text="", - const std::string& reference_to="", bool floating=false, - bool box=false, ALIGNMENT alignment=HERE); - - item(const texture& tex, int x, int y, - bool floating, bool box=false, ALIGNMENT=HERE); - - /** Relative coordinates of this item. */ - rect rect_; - - texture tex; - - // If this item contains text, this will contain that text. - std::string text; - - // If this item contains a cross-reference, this is the id - // of the referenced topic. - std::string ref_to; - - // If this item is floating, that is, if things should be filled - // around it. - bool floating; - bool box; - ALIGNMENT align; - }; - - /** Function object to find an item at the specified coordinates. */ - class item_at { - public: - item_at(const int x, const int y) : x_(x), y_(y) {} - bool operator()(const item&) const; - private: - const int x_, y_; - }; - - /** - * Update the vector with the items of the shown topic, creating - * surfaces for everything and putting things where they belong. - */ - void set_items(); - - // Create appropriate items from configs. Items will be added to the - // internal vector. These methods check that the necessary - // attributes are specified. - void handle_ref_cfg(const config &cfg); - void handle_img_cfg(const config &cfg); - void handle_bold_cfg(const config &cfg); - void handle_italic_cfg(const config &cfg); - void handle_header_cfg(const config &cfg); - void handle_jump_cfg(const config &cfg); - void handle_format_cfg(const config &cfg); - void handle_text_cfg(const config &cfg); - - void draw_contents(); - - /** - * Add an item with text. If ref_dst is something else than the - * empty string, the text item will be underlined to show that it - * is a cross-reference. The item will also remember what the - * reference points to. If font_size is below zero, the default - * will be used. - */ - void add_text_item(const std::string& text, const std::string& ref_dst="", - bool broken_link = false, - int font_size=-1, bool bold=false, bool italic=false, - color_t color=font::NORMAL_COLOR); - - /** Add an image item with the specified attributes. */ - void add_img_item(const std::string& path, const std::string& alignment, const bool floating, - const bool box); - - /** Move the current input point to the next line. */ - void down_one_line(); - - /** Adjust the heights of the items in the last row to make it look good. */ - void adjust_last_row(); - - /** Return the width that remain on the line the current input point is at. */ - int get_remaining_width(); - - /** - * Return the least x coordinate at which something of the - * specified height can be drawn at the specified y coordinate - * without interfering with floating images. - */ - int get_min_x(const int y, const int height=0); - - /** Analogous with get_min_x but return the maximum X. */ - int get_max_x(const int y, const int height=0); - - /** - * Find the lowest y coordinate where a floating img of the - * specified width and at the specified x coordinate can be - * placed. Start looking at desired_y and continue downwards. Only - * check against other floating things, since text and inline - * images only can be above this place if called correctly. - */ - int get_y_for_floating_img(const int width, const int x, const int desired_y); - - /** Add an item to the internal list, update the locations and row height. */ - void add_item(const item& itm); - - std::list items_; - std::list last_row_; - const section &toplevel_; - topic const *shown_topic_; - const int title_spacing_; - /** The current input location when creating items. */ - std::pair curr_loc_; - const unsigned min_row_height_; - unsigned curr_row_height_; - /** The height of all items in total. */ - int contents_height_; -}; - -} // end namespace help