The Battle for Wesnoth  1.13.4+dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
help_browser.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_browser.hpp"
16 #include <iostream> // for operator<<, basic_ostream, etc
17 #include <SDL_mouse.h> // for SDL_GetMouseState, etc
18 #include "cursor.hpp" // for set, CURSOR_TYPE::HYPERLINK, etc
19 #include "font.hpp" // for relative_size
20 #include "gettext.hpp" // for _
22 #include "help/help_text_area.hpp" // for help_text_area
23 #include "help_impl.hpp" // for find_topic, hidden_symbol, etc
24 #include "key.hpp" // for CKey
25 #include "log.hpp" // for log_scope
26 #include "sdl/rect.hpp"
27 
28 class CVideo;
29 struct SDL_Rect;
30 
31 namespace help {
32 
34  gui::widget(video),
35  menu_(video,
36  toplevel),
37  text_area_(video, toplevel), toplevel_(toplevel),
38  ref_cursor_(false),
39  back_topics_(),
40  forward_topics_(),
41  back_button_(video, "", gui::button::TYPE_PRESS, "button_normal/button_small_H22", gui::button::DEFAULT_SPACE, true, "icons/arrows/long_arrow_ornate_left"),
42  forward_button_(video, "", gui::button::TYPE_PRESS, "button_normal/button_small_H22", gui::button::DEFAULT_SPACE, true, "icons/arrows/long_arrow_ornate_right"),
43  shown_topic_(nullptr)
44 {
45  // Hide the buttons at first since we do not have any forward or
46  // back topics at this point. They will be unhidden when history
47  // appears.
48  back_button_.hide(true);
49  forward_button_.hide(true);
50  // Set sizes to some default values.
52 }
53 
55 {
56  const int menu_buttons_padding = font::relative_size(10);
57  const int menu_y = location().y;
58  const int menu_x = location().x;
59  const int menu_w = 250;
60  const int menu_h = height();
61 
62  const int menu_text_area_padding = font::relative_size(10);
63  const int text_area_y = location().y;
64  const int text_area_x = menu_x + menu_w + menu_text_area_padding;
65  const int text_area_w = width() - menu_w - menu_text_area_padding;
66  const int text_area_h = height();
67 
68  const int button_border_padding = 0;
69  const int button_button_padding = font::relative_size(10);
70  const int back_button_x = location().x + button_border_padding;
71  const int back_button_y = menu_y + menu_h + menu_buttons_padding;
72  const int forward_button_x = back_button_x + back_button_.width() + button_button_padding;
73  const int forward_button_y = back_button_y;
74 
75  menu_.set_width(menu_w);
76  menu_.set_location(menu_x, menu_y);
77  menu_.set_max_height(menu_h);
78  menu_.set_max_width(menu_w);
79 
80  text_area_.set_location(text_area_x, text_area_y);
81  text_area_.set_width(text_area_w);
82  text_area_.set_height(text_area_h);
83 
84  back_button_.set_location(back_button_x, back_button_y);
85  forward_button_.set_location(forward_button_x, forward_button_y);
86 
87  set_dirty(true);
88 }
89 
90 void help_browser::update_location(SDL_Rect const &)
91 {
92  adjust_layout();
93 }
94 
96 {
97  CKey key;
98  int mousex, mousey;
99  SDL_GetMouseState(&mousex,&mousey);
100 
101  /// Fake focus functionality for the menu, only process it if it has focus.
102  if (sdl::point_in_rect(mousex, mousey, menu_.location())) {
103  menu_.process();
104  const topic *chosen_topic = menu_.chosen_topic();
105  if (chosen_topic != nullptr && chosen_topic != shown_topic_) {
106  /// A new topic has been chosen in the menu, display it.
107  show_topic(*chosen_topic);
108  }
109  }
110  if (back_button_.pressed()) {
112  }
113  if (forward_button_.pressed()) {
115  }
116  back_button_.hide(back_topics_.empty());
118 }
119 
120 void help_browser::move_in_history(std::deque<const topic *> &from,
121  std::deque<const topic *> &to)
122 {
123  if (!from.empty()) {
124  const topic *to_show = from.back();
125  from.pop_back();
126  if (shown_topic_ != nullptr) {
127  if (to.size() > max_history) {
128  to.pop_front();
129  }
130  to.push_back(shown_topic_);
131  }
132  show_topic(*to_show, false);
133  }
134 }
135 
136 
137 void help_browser::handle_event(const SDL_Event &event)
138 {
140 
141  SDL_MouseButtonEvent mouse_event = event.button;
142  if (event.type == SDL_MOUSEBUTTONDOWN) {
143  if (mouse_event.button == SDL_BUTTON_LEFT) {
144  // Did the user click a cross-reference?
145  const int mousex = mouse_event.x;
146  const int mousey = mouse_event.y;
147  const std::string ref = text_area_.ref_at(mousex, mousey);
148  if (ref != "") {
149  const topic *t = find_topic(toplevel_, ref);
150  if (t == nullptr) {
151  std::stringstream msg;
152  msg << _("Reference to unknown topic: ") << "'" << ref << "'.";
153  gui2::show_transient_message(video(), "", msg.str());
154  update_cursor();
155  }
156  else {
157  show_topic(*t);
158  update_cursor();
159  }
160  }
161  }
162  }
163  else if (event.type == SDL_MOUSEMOTION) {
164  update_cursor();
165  }
166 }
167 
169 {
170  int mousex, mousey;
171  SDL_GetMouseState(&mousex,&mousey);
172  const std::string ref = text_area_.ref_at(mousex, mousey);
173  if (ref != "" && !ref_cursor_) {
175  ref_cursor_ = true;
176  }
177  else if (ref == "" && ref_cursor_) {
179  ref_cursor_ = false;
180  }
181 }
182 
184 {
185  const topic *t = find_topic(toplevel_, topic_id);
186 
187  if (t != nullptr) {
188  show_topic(*t);
189  } else if (topic_id.find(unit_prefix)==0 || topic_id.find(hidden_symbol() + unit_prefix)==0) {
191  } else {
192  std::cerr << "Help browser tried to show topic with id '" << topic_id
193  << "' but that topic could not be found." << std::endl;
194  }
195 }
196 
197 void help_browser::show_topic(const topic &t, bool save_in_history)
198 {
199  log_scope("show_topic");
200 
201  if (save_in_history) {
202  forward_topics_.clear();
203  if (shown_topic_ != nullptr) {
204  if (back_topics_.size() > max_history) {
205  back_topics_.pop_front();
206  }
207  back_topics_.push_back(shown_topic_);
208  }
209  }
210 
211  shown_topic_ = &t;
213  menu_.select_topic(t);
214  update_cursor();
215 }
216 
217 
218 } // end namespace help
void update_cursor()
Update the current cursor, set it to the reference cursor if mousex, mousey is over a cross-reference...
gui::button forward_button_
void move_in_history(std::deque< const topic * > &from, std::deque< const topic * > &to)
Move in the topic history.
const std::string unit_prefix
Definition: help_impl.cpp:88
void set(CURSOR_TYPE type)
Use the default parameter to reset cursors.
Definition: cursor.cpp:154
A section contains topics and sections along with title and ID.
Definition: help_impl.hpp:143
topic const * shown_topic_
const std::string unknown_unit_topic
Definition: help_impl.cpp:87
Definition: video.hpp:58
int relative_size(int size)
Definition: font.hpp:72
help::section toplevel
Definition: help_impl.cpp:66
CVideo & video() const
Definition: widget.hpp:83
General purpose widgets.
virtual void handle_event(const SDL_Event &event)
void set_width(int w)
Definition: widget.cpp:119
help_browser(CVideo &video, const section &toplevel)
std::deque< const topic * > forward_topics_
void show_transient_message(CVideo &video, const std::string &title, const std::string &message, const std::string &image, const bool message_use_markup, const bool title_use_markup, const bool restore_background)
Shows a transient message to the user.
GLdouble GLdouble t
Definition: glew.h:1366
const section & toplevel_
void set_measurements(int w, int h)
Definition: widget.cpp:129
void set_dirty(bool dirty=true)
Definition: widget.cpp:217
static UNUSEDNOWARN std::string _(const char *str)
Definition: gettext.hpp:82
std::string hidden_symbol(bool hidden)
Definition: help_impl.cpp:1347
std::deque< const topic * > back_topics_
std::string ref_at(const int x, const int y)
Return the ID that is cross-referenced at the (screen) coordinates x, y.
virtual void hide(bool value=true)
Definition: widget.cpp:162
gui::button back_button_
void set_max_width(const int new_max_width)
Definition: menu.cpp:485
bool pressed()
Definition: button.cpp:770
bool point_in_rect(int x, int y, const SDL_Rect &rect)
Tests whether a point is inside a rectangle.
Definition: rect.cpp:47
void show_topic(const topic &t)
Display the topic.
void show_topic(const std::string &topic_id)
Display the topic with the specified identifier.
virtual void process_event()
virtual void update_location(SDL_Rect const &rect)
#define log_scope(description)
Definition: log.hpp:185
static void msg(const char *act, debug_info &i, const char *to="", const char *result="")
Definition: debugger.cpp:112
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
const unsigned max_history
Definition: help_impl.cpp:81
Contains the SDL_Rect helper code.
GLenum GLint ref
Definition: glew.h:1813
cl_event event
Definition: glew.h:3070
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
Standard logging facilities (interface).
A topic contains a title, an id and some text.
Definition: help_impl.hpp:111
virtual void set_location(SDL_Rect const &rect)
Definition: widget.cpp:85
const topic * chosen_topic()
If a topic has been chosen, return that topic, otherwise nullptr.
Definition: help_menu.cpp:197
virtual void handle_event(SDL_Event const &)
Definition: widget.cpp:345
Definition: help.cpp:57
int width() const
Definition: widget.cpp:134
SDL_Rect const & location() const
Definition: widget.cpp:144
Class that keeps track of all the keys on the keyboard.
Definition: key.hpp:27
void set_height(int h)
Definition: widget.cpp:124
GLsizei const GLcharARB ** string
Definition: glew.h:4503
void set_max_height(const int new_max_height)
Set a new max height for this menu.
Definition: menu.cpp:477
help_text_area text_area_
int height() const
Definition: widget.cpp:139