32 #define WRN_DP LOG_STREAM(warn, log_display) 35 #define ERR_HP LOG_STREAM(err, log_help) 36 #define WRN_HP LOG_STREAM(warn, log_help) 37 #define DBG_HP LOG_STREAM(debug, log_help) 42 gui::scrollarea(video),
46 shown_topic_(nullptr),
50 curr_row_height_(min_row_height_),
68 DBG_HP <<
"Showing topic: " << t.
id <<
": " << t.
title << std::endl;
73 const std::string& reference_to,
bool _floating,
79 floating(_floating), box(_box),
111 const std::string show_title =
115 if (surf !=
nullptr) {
123 std::vector<std::string>::const_iterator it;
124 for (it = parsed_items.begin(); it != parsed_items.end(); ++it) {
125 if (!(*it).empty() && (*it)[0] ==
'[') {
129 std::istringstream stream(*it);
132 #define TRY(name) do { \ 133 if (config &child = cfg.child(#name)) \ 134 handle_##name##_cfg(child); \ 149 std::stringstream
msg;
150 msg <<
"Error when parsing help markup as WML: '" << e.
message <<
"'";
167 const std::string dst = cfg[
"dst"];
168 const std::string
text = cfg[
"text"];
169 bool force = cfg[
"force"].to_bool();
172 std::stringstream
msg;
173 msg <<
"Ref markup must have dst attribute. Please submit a bug" 174 " report if you have not modified the game files yourself. Erroneous config: ";
196 std::stringstream
msg;
197 msg <<
"Reference to non-existent topic '" << dst
198 <<
"'. Please submit a bug report if you have not" 199 "modified the game files yourself. Erroneous config: ";
211 const std::string src = cfg[
"src"];
212 const std::string
align = cfg[
"align"];
213 bool floating = cfg[
"float"].to_bool();
214 bool box = cfg[
"box"].to_bool(
true);
216 throw parse_error(
"Img markup must have src attribute.");
223 const std::string
text = cfg[
"text"];
225 throw parse_error(
"Bold markup must have text attribute.");
232 const std::string
text = cfg[
"text"];
234 throw parse_error(
"Italic markup must have text attribute.");
241 const std::string
text = cfg[
"text"];
243 throw parse_error(
"Header markup must have text attribute.");
250 const std::string amount_str = cfg[
"amount"];
251 const std::string to_str = cfg[
"to"];
252 if (amount_str.empty() && to_str.empty()) {
253 throw parse_error(
"Jump markup must have either a to or an amount attribute.");
256 if (!amount_str.empty()) {
259 amount =
lexical_cast<unsigned, std::string>(amount_str);
262 throw parse_error(
"Invalid amount the amount attribute in jump markup.");
266 if (!to_str.empty()) {
272 throw parse_error(
"Invalid amount in the to attribute in jump markup.");
279 if (jump_to != 0 && static_cast<int>(jump_to) <
288 const std::string
text = cfg[
"text"];
290 throw parse_error(
"Format markup must have text attribute.");
292 bool bold = cfg[
"bold"].to_bool();
293 bool italic = cfg[
"italic"].to_bool();
296 add_text_item(text,
"",
false, font_size, bold, italic, color);
300 bool broken_link,
int _font_size,
bool bold,
bool italic,
310 std::size_t first_word_start = text.find_first_not_of(
" ");
311 if (first_word_start == std::string::npos) {
312 first_word_start = 0;
314 if (text[first_word_start] ==
'\n') {
316 std::string rest_text =
text;
317 rest_text.erase(0, first_word_start + 1);
318 add_text_item(rest_text, ref_dst, broken_link, _font_size, bold, italic, text_color);
323 state |= bold ? TTF_STYLE_BOLD : 0;
324 state |= italic ? TTF_STYLE_ITALIC : 0;
326 && remaining_width <
font::line_width(first_word, scaled_font_size, state)) {
331 add_text_item(s, ref_dst, broken_link, _font_size, bold, italic, text_color);
334 std::vector<std::string> parts =
split_in_width(text, font_size, remaining_width);
335 std::string first_part = parts.front();
348 if (first_part.empty()) {
356 if (parts.size() > 1) {
358 std::string&
s = parts.back();
375 add_text_item(s, ref_dst, broken_link, _font_size, bold, italic, text_color);
388 if (align ==
HERE && floating) {
389 WRN_DP <<
"Floating image with align HERE, aligning left." << std::endl;
405 xpos = text_width / 2 - width / 2 - (box ?
box_width : 0);
408 xpos = text_width - width - (box ?
box_width * 2 : 0);
412 && (xpos <
curr_loc_.first || xpos + width > text_width)) {
429 int min_y = desired_y;
430 for (std::list<item>::const_iterator it =
items_.begin(); it !=
items_.end(); ++it) {
431 const item& itm = *it;
433 if ((itm.
rect.x + itm.
rect.w > x && itm.
rect.x < x + width)
435 min_y = std::max<int>(min_y, itm.
rect.y + itm.
rect.h);
445 for (std::list<item>::const_iterator it =
items_.begin(); it !=
items_.end(); ++it) {
446 const item& itm = *it;
449 min_x = std::max<int>(min_x, itm.
rect.w + 5);
459 int max_x = text_width;
460 for (std::list<item>::const_iterator it =
items_.begin(); it !=
items_.end(); ++it) {
461 const item& itm = *it;
463 if (itm.
rect.y < y + height && itm.
rect.y + itm.
rect.h > y) {
465 max_x = std::min<int>(max_x, text_width - itm.
rect.w - 5);
467 max_x = std::min<int>(max_x, text_width / 2 - itm.
rect.w / 2 - 5);
495 if (cmp_str ==
"left") {
497 }
else if (cmp_str ==
"middle") {
499 }
else if (cmp_str ==
"right") {
501 }
else if (cmp_str ==
"here" || cmp_str.empty()) {
504 std::stringstream
msg;
505 msg <<
"Invalid alignment string: '" << cmp_str <<
"'";
524 itm.
rect.y += gap / 2;
540 for(std::list<item>::const_iterator it =
items_.begin(), end =
items_.end(); it != end; ++it) {
541 SDL_Rect dst = it->rect;
543 if (dst.y < static_cast<int>(loc.h) && dst.y + it->rect.h > 0) {
559 SDL_FillRect(screen, &draw_rect, 0);
564 sdl_blit(it->surf,
nullptr, screen, &dst);
583 const int local_x = x -
location().x;
584 const int local_y = y -
location().y;
585 if (local_y <
height() && local_y > 0) {
587 const std::list<item>::const_iterator it =
590 if (!(*it).ref_to.empty()) {
591 return ((*it).ref_to);
std::string jump_to(const unsigned pos)
int get_max_x(const int y, const int height=0)
Analogous with get_min_x but return the maximum X.
surface get_image(const image::locator &i_locator, TYPE type)
Caches and returns an image.
help_text_area(CVideo &video, const section &toplevel)
virtual void set_inner_location(const SDL_Rect &rect)
Note: Specific to sdl_ttf.
void add_img_item(const std::string &path, const std::string &alignment, const bool floating, const bool box)
Add an image item with the specified attributes.
std::string remove_first_space(const std::string &text)
A section contains topics and sections along with title and ID.
int get_remaining_width()
Return the width that remain on the line the current input point is at.
int get_y_for_floating_img(const int width, const int x, const int desired_y)
Find the lowest y coordinate where a floating img of the specified width and at the specified x coord...
Thrown when the help system fails to parse something.
std::list< item * > last_row_
static void msg(const char *act, debug_info &i, const char *to="", const char *result="")
const int normal_font_size
void set_items()
Update the vector with the items of the shown topic, creating surfaces for everything and putting thi...
To lexical_cast(From value)
Lexical cast converts one type to another.
color_t string_to_color(const std::string &cmp_str)
Return the color the string represents.
Definitions for the interface to Wesnoth Markup Language (WML).
surface & getSurface()
Returns a reference to the framebuffer.
std::string bold(const std::string &s)
topic const * shown_topic_
void write(std::ostream &out, const configr_of &cfg, unsigned int level)
void read(config &cfg, std::istream &in, abstract_validator *validator)
void add_item(const item &itm)
Add an item to the internal list, update the locations and row height.
std::string ref_at(const int x, const int y)
Return the ID that is cross-referenced at the (screen) coordinates x, y.
int font_scaled(int size)
virtual void scroll(unsigned int pos)
const section & toplevel_
void handle_ref_cfg(const config &cfg)
const unsigned min_row_height_
const color_t YELLOW_COLOR
void handle_img_cfg(const config &cfg)
int get_max_height(int size)
const color_t NORMAL_COLOR
bool point_in_rect(int x, int y, const SDL_Rect &rect)
Tests whether a point is inside a rectangle.
void handle_header_cfg(const config &cfg)
An item that is displayed in the text area.
void handle_italic_cfg(const config &cfg)
void handle_bold_cfg(const config &cfg)
void show_topic(const topic &t)
Display the topic.
void adjust_last_row()
Adjust the heights of the items in the last row to make it look good.
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 item with text.
static map_location::DIRECTION s
std::pair< int, int > curr_loc_
The current input location when creating items.
item(surface surface, int x, int y, const std::string &text="", const std::string &reference_to="", bool floating=false, bool box=false, ALIGNMENT alignment=HERE)
surface get_rendered_text(const std::string &str, int size, const color_t &color, int style)
static lg::log_domain log_help("help")
int get_min_x(const int y, const int height=0)
Return the least x coordinate at which something of the specified height can be drawn at the specifie...
void down_one_line()
Move the current input point to the next line.
std::string make_text_ellipsis(const std::string &text, int font_size, int max_width, int style)
If the text exceeds the specified max width, end it with an ellipsis (...)
std::string jump(const unsigned amount)
Contains the SDL_Rect helper code.
void handle_format_cfg(const config &cfg)
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.
const std::vector< std::string > & parsed_text() const
Standard logging facilities (interface).
A topic contains a title, an id and some text.
ALIGNMENT str_to_align(const std::string &s)
Convert a string to an alignment.
bool operator()(const item &) const
SDL_Rect rect
Relative coordinates of this item.
void sdl_blit(const surface &src, SDL_Rect *src_rect, surface &dst, SDL_Rect *dst_rect)
A config object defines a single node in a WML file, with access to child nodes.
static lg::log_domain log_display("display")
std::string get_first_word(const std::string &s)
Return the first word in s, not removing any spaces in the start of it.
int contents_height_
The height of all items in total.
Thrown when a lexical_cast fails.
int line_width(const std::string &line, int font_size, int style)
Determine the width of a line of text given a certain font size.
std::string::const_iterator iterator
void handle_jump_cfg(const config &cfg)
std::vector< std::string > split_in_width(const std::string &s, const int font_size, const unsigned width)
Make a best effort to word wrap s.
unsigned curr_row_height_
Function object to find an item at the specified coordinates.