The Battle for Wesnoth  1.13.4+dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
help_menu.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2003 - 2016 by David White <[email protected]>
3  Part of the Battle for Wesnoth Project http://www.wesnoth.org/
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY.
11 
12  See the COPYING file for more details.
13 */
14 
15 #include "help_menu.hpp"
16 
17 #include "game_config.hpp" // for menu_contract, menu_expand
18 #include "help_impl.hpp" // for section, topic, topic_list, etc
19 #include "sound.hpp" // for play_UI_sound
20 #include "wml_separators.hpp" // for IMG_TEXT_SEPARATOR, etc
21 
22 #include <algorithm> // for find
23 #include <iostream> // for basic_ostream, operator<<, etc
24 #include <list> // for _List_const_iterator, etc
25 #include <utility> // for pair
26 #include <SDL.h>
27 
28 class CVideo; // lines 56-56
29 
30 namespace help {
31 
32 help_menu::help_menu(CVideo &video, section const &toplevel, int max_height) :
33  gui::menu(video, empty_string_vector, true, max_height, -1, nullptr, &gui::menu::bluebg_style),
34  visible_items_(),
35  toplevel_(toplevel),
36  expanded_(),
37  restorer_(),
38  chosen_topic_(nullptr),
39  selected_item_(&toplevel, "")
40 {
41  silent_ = true; //silence the default menu sounds
44  if (!visible_items_.empty())
46 }
47 
48 bool help_menu::expanded(const section &sec)
49 {
50  return expanded_.find(&sec) != expanded_.end();
51 }
52 
53 void help_menu::expand(const section &sec)
54 {
55  if (sec.id != "toplevel" && expanded_.insert(&sec).second) {
57  }
58 }
59 
60 void help_menu::contract(const section &sec)
61 {
62  if (expanded_.erase(&sec)) {
64  }
65 }
66 
67 void help_menu::update_visible_items(const section &sec, unsigned level)
68 {
69  if (level == 0) {
70  // Clear if this is the top level, otherwise append items.
71  visible_items_.clear();
72  }
73  section_list::const_iterator sec_it;
74  for (sec_it = sec.sections.begin(); sec_it != sec.sections.end(); ++sec_it) {
75  if (is_visible_id((*sec_it)->id)) {
76  const std::string vis_string = get_string_to_show(*(*sec_it), level + 1);
77  visible_items_.push_back(visible_item(*sec_it, vis_string));
78  if (expanded(*(*sec_it))) {
79  update_visible_items(*(*sec_it), level + 1);
80  }
81  }
82  }
83  topic_list::const_iterator topic_it;
84  for (topic_it = sec.topics.begin(); topic_it != sec.topics.end(); ++topic_it) {
85  if (is_visible_id(topic_it->id)) {
86  const std::string vis_string = get_string_to_show(*topic_it, level + 1);
87  visible_items_.push_back(visible_item(&(*topic_it), vis_string));
88  }
89  }
90 }
91 
92 std::string help_menu::indent_list(const std::string& icon, const unsigned level) {
93  std::stringstream to_show;
94  for (unsigned i = 1; i < level; ++i) {
95  to_show << " "; // Indent 4 spaces
96  }
97 
98  to_show << IMG_TEXT_SEPARATOR << IMAGE_PREFIX << icon;
99  return to_show.str();
100 }
101 
103 {
104  std::stringstream to_show;
105  to_show << indent_list(expanded(sec) ? open_section_img : closed_section_img, level)
106  << IMG_TEXT_SEPARATOR << sec.title;
107  return to_show.str();
108 }
109 
111 {
112  std::stringstream to_show;
113  to_show << indent_list(topic_img, level)
114  << IMG_TEXT_SEPARATOR << topic.title;
115  return to_show.str();
116 }
117 
119 {
120  topic_list::const_iterator tit =
121  std::find(sec.topics.begin(), sec.topics.end(), t);
122  if (tit != sec.topics.end()) {
123  // topic starting with ".." are assumed as rooted in the parent section
124  // and so only expand the parent when selected
125  if (t.id.size()<2 || t.id[0] != '.' || t.id[1] != '.')
126  expand(sec);
127  return true;
128  }
129  section_list::const_iterator sit;
130  for (sit = sec.sections.begin(); sit != sec.sections.end(); ++sit) {
131  if (select_topic_internal(t, *(*sit))) {
132  expand(sec);
133  return true;
134  }
135  }
136  return false;
137 }
138 
140 {
141  if (selected_item_ == t) {
142  // The requested topic is already selected.
143  return;
144  }
147  for (std::vector<visible_item>::const_iterator it = visible_items_.begin();
148  it != visible_items_.end(); ++it) {
149  if (*it == t) {
150  selected_item_ = *it;
151  break;
152  }
153  }
155  }
156 }
157 
159 {
160  int res = menu::process();
161  int mousex, mousey;
162  SDL_GetMouseState(&mousex,&mousey);
163 
164  if (!visible_items_.empty() &&
165  static_cast<size_t>(res) < visible_items_.size()) {
166 
168  const section* sec = selected_item_.sec;
169  if (sec != nullptr) {
170  // Check how we click on the section
171  int x = mousex - menu::location().x;
172 
173  const std::string icon_img = expanded(*sec) ? open_section_img : closed_section_img;
174  // we remove the right thickness (ne present between icon and text)
175  int text_start = style_->item_size(indent_list(icon_img, sec->level)).w - style_->get_thickness();
176 
177  // NOTE: if you want to forbid click to the left of the icon
178  // also check x >= text_start-image_width(icon_img)
179  if (menu::double_clicked() || x < text_start) {
180  // Open or close a section if we double-click on it
181  // or do simple click on the icon.
182  expanded(*sec) ? contract(*sec) : expand(*sec);
185  } else if (x >= text_start){
186  // click on title open the topic associated to this section
187  chosen_topic_ = find_topic(toplevel, ".."+sec->id );
188  }
189  } else if (selected_item_.t != nullptr) {
190  /// Choose a topic if it is clicked.
192  }
193  }
194  return res;
195 }
196 
198 {
199  const topic *ret = chosen_topic_;
200  chosen_topic_ = nullptr;
201  return ret;
202 }
203 
205 {
206  std::vector<std::string> menu_items;
207  for(std::vector<visible_item>::const_iterator items_it = visible_items_.begin(),
208  end = visible_items_.end(); items_it != end; ++items_it) {
209  std::string to_show = items_it->visible_string;
210  if (selected_item_ == *items_it)
211  to_show = std::string("*") + to_show;
212  menu_items.push_back(to_show);
213  }
214  set_items(menu_items, false, true);
215 }
216 
218  t(nullptr), sec(_sec), visible_string(vis_string) {}
219 
221  t(_t), sec(nullptr), visible_string(vis_string) {}
222 
224 {
225  return sec != nullptr && *sec == _sec;
226 }
227 
229 {
230  return t != nullptr && *t == _t;
231 }
232 
234 {
235  return t == vis_item.t && sec == vis_item.sec;
236 }
237 
238 } // end namespace help
void contract(const section &sec)
Contract (close) a section.
Definition: help_menu.cpp:60
std::string get_string_to_show(const section &sec, const unsigned level)
Return the string to use as the menu-string for sections at the specified level.
Definition: help_menu.cpp:102
char const IMG_TEXT_SEPARATOR
std::string id
Definition: help_impl.hpp:165
const std::string open_section_img
Definition: help_impl.cpp:84
const std::string topic_img
Definition: help_impl.cpp:82
visible_item selected_item_
Definition: help_menu.hpp:98
topic const * chosen_topic_
Definition: help_menu.hpp:97
visible_item(const section *_sec, const std::string &visible_string)
Definition: help_menu.cpp:217
GLint level
Definition: glew.h:1220
const std::string closed_section_img
Definition: help_impl.cpp:83
A section contains topics and sections along with title and ID.
Definition: help_impl.hpp:143
const std::string menu_expand
Definition: video.hpp:58
help::section toplevel
Definition: help_impl.cpp:66
General purpose widgets.
std::vector< std::string > empty_string_vector
Definition: help_impl.cpp:75
bool expanded(const section &sec)
Return true if the section is expanded.
Definition: help_menu.cpp:48
GLdouble GLdouble t
Definition: glew.h:1366
bool is_visible_id(const std::string &id)
Definition: help_impl.cpp:1351
char const IMAGE_PREFIX
section_list sections
Definition: help_impl.hpp:167
std::string id
Definition: help_impl.hpp:136
void process(int mousex, int mousey)
Definition: tooltips.cpp:198
GLuint GLuint end
Definition: glew.h:1221
void display_visible_items()
Draw the currently visible items.
Definition: help_menu.cpp:204
bool operator==(const visible_item &vis_item) const
Definition: help_menu.cpp:233
std::string title
Definition: help_impl.hpp:165
const section & toplevel_
Definition: help_menu.hpp:94
size_t get_thickness() const
Definition: menu_style.cpp:62
std::string indent_list(const std::string &icon, const unsigned level)
Return the string to use as the prefix for the icon part of the menu-string at the specified level...
Definition: help_menu.cpp:92
Information about an item that is visible in the menu.
Definition: help_menu.hpp:48
void expand(const section &sec)
Mark a section as expanded.
Definition: help_menu.cpp:53
help_menu(CVideo &video, const section &toplevel, int max_height=-1)
Definition: help_menu.cpp:32
virtual void set_items(const std::vector< std::string > &items, bool strip_spaces=true, bool keep_viewport=false)
Set new items to show and redraw/recalculate everything.
Definition: menu.cpp:446
GLuint res
Definition: glew.h:9258
std::set< const section * > expanded_
Definition: help_menu.hpp:95
std::vector< visible_item > visible_items_
Definition: help_menu.hpp:93
const std::string menu_contract
size_t i
Definition: function.cpp:1057
GLint GLint GLint GLint GLint x
Definition: glew.h:1220
void select_topic(const topic &t)
Make the topic the currently selected one, and expand all sections that need to be expanded to show i...
Definition: help_menu.cpp:139
bool find(E event, F functor)
Tests whether an event handler is available.
const topic * find_topic(const section &sec, const std::string &id)
Search for the topic with the specified identifier in the section and its subsections.
Definition: help_impl.cpp:1049
void play_UI_sound(const std::string &files)
Definition: sound.cpp:842
A topic contains a title, an id and some text.
Definition: help_impl.hpp:111
void update_visible_items(const section &top_level, unsigned starting_level=0)
Regenerate what items are visible by checking what sections are expanded.
Definition: help_menu.cpp:67
const topic * chosen_topic()
If a topic has been chosen, return that topic, otherwise nullptr.
Definition: help_menu.cpp:197
bool silent_
Definition: menu.hpp:233
Definition: help.cpp:57
map_location location
std::string title
Definition: help_impl.hpp:136
bool select_topic_internal(const topic &t, const section &sec)
Internal recursive thingie.
Definition: help_menu.cpp:118
GLsizei const GLcharARB ** string
Definition: glew.h:4503
topic_list topics
Definition: help_impl.hpp:166
style * style_
Definition: menu.hpp:232
virtual SDL_Rect item_size(const std::string &item) const
Definition: menu.cpp:804