← Back to team overview

widelands-dev team mailing list archive

[Merge] lp:~widelands-dev/widelands/revise-map-descr into lp:widelands

 

GunChleoc has proposed merging lp:~widelands-dev/widelands/revise-map-descr into lp:widelands.

Commit message:
Revised map details in map loading screens. Localized map tags everywhere.

Requested reviews:
  Widelands Developers (widelands-dev)

For more details, see:
https://code.launchpad.net/~widelands-dev/widelands/revise-map-descr/+merge/292031

It became impossible to scroll through some map descriptions, so I put it all into one big richtext area. This means that I could also add some more info like map size and tags.
-- 
Your team Widelands Developers is requested to review the proposed merge of lp:~widelands-dev/widelands/revise-map-descr into lp:widelands.
=== modified file 'src/editor/ui_menus/main_menu_map_options.cc'
--- src/editor/ui_menus/main_menu_map_options.cc	2016-04-06 09:23:04 +0000
+++ src/editor/ui_menus/main_menu_map_options.cc	2016-04-15 17:37:26 +0000
@@ -33,6 +33,7 @@
 #include "ui_basic/multilineeditbox.h"
 #include "ui_basic/multilinetextarea.h"
 #include "ui_basic/textarea.h"
+#include "wui/map_tags.h"
 
 inline EditorInteractive & MainMenuMapOptions::eia() {
 	return dynamic_cast<EditorInteractive&>(*get_parent());
@@ -122,12 +123,12 @@
 
 
 	tags_box_.add(new UI::Textarea(&tags_box_, 0, 0, max_w_, labelh_, _("Tags:")), UI::Align::kLeft);
-	add_tag_checkbox(&tags_box_, "unbalanced", _("Unbalanced"));
-	add_tag_checkbox(&tags_box_, "ffa", _("Free for all"));
-	add_tag_checkbox(&tags_box_, "1v1", _("1v1"));
-	add_tag_checkbox(&tags_box_, "2teams", _("Teams of 2"));
-	add_tag_checkbox(&tags_box_, "3teams", _("Teams of 3"));
-	add_tag_checkbox(&tags_box_, "4teams", _("Teams of 4"));
+	add_tag_checkbox(&tags_box_, "unbalanced", localize_tag("unbalanced"));
+	add_tag_checkbox(&tags_box_, "ffa", localize_tag("ffa"));
+	add_tag_checkbox(&tags_box_, "1v1", localize_tag("1v1"));
+	add_tag_checkbox(&tags_box_, "2teams", localize_tag("2teams"));
+	add_tag_checkbox(&tags_box_, "3teams", localize_tag("3teams"));
+	add_tag_checkbox(&tags_box_, "4teams", localize_tag("4teams"));
 
 	teams_box_.add(new UI::Textarea(&teams_box_, 0, 0, max_w_, labelh_, _("Suggested Teams:")),
 						UI::Align::kLeft);

=== modified file 'src/graphic/text/rt_parse.cc'
--- src/graphic/text/rt_parse.cc	2016-03-14 19:49:52 +0000
+++ src/graphic/text/rt_parse.cc	2016-04-15 17:37:26 +0000
@@ -274,6 +274,7 @@
 
 		tc.allowed_children.insert("br");
 		tc.allowed_children.insert("space");
+		tc.allowed_children.insert("vspace");
 		tc.allowed_children.insert("p");
 		tc.allowed_children.insert("font");
 		tc.allowed_children.insert("sub");

=== modified file 'src/ui_basic/multilinetextarea.cc'
--- src/ui_basic/multilinetextarea.cc	2016-04-01 09:29:17 +0000
+++ src/ui_basic/multilinetextarea.cc	2016-04-15 17:37:26 +0000
@@ -41,7 +41,8 @@
 	Panel       (parent, x, y, w, h),
 	text_      (text),
 	color_(UI_FONT_CLR_FG),
-	isrichtext(false),
+	force_new_renderer_(false),
+	use_old_renderer_(false),
 	scrollbar_ (this, get_w() - Scrollbar::kSize, 0, Scrollbar::kSize, h, false),
 	scrollmode_(scroll_mode)
 {
@@ -88,12 +89,16 @@
 	// We wrap the text twice. We need to do this to account for the presence/absence of the scollbar.
 	bool scrollbar_was_enabled = scrollbar_.is_enabled();
 	for (int i = 0; i < 2; ++i) {
-		if (text_.compare(0, 3, "<rt")) {
-			isrichtext = false;
+		if (!is_richtext(text_)) {
+			use_old_renderer_ = false;
 			const Image* text_im = UI::g_fh1->render(make_richtext(), get_eff_w() - 2 * RICHTEXT_MARGIN);
 			height = text_im->height();
+		} else if (force_new_renderer_) {
+			use_old_renderer_ = false;
+			const Image* text_im = UI::g_fh1->render(text_, get_eff_w() - 2 * RICHTEXT_MARGIN);
+			height = text_im->height();
 		} else {
-			isrichtext = true;
+			use_old_renderer_ = true;
 			rt.set_width(get_eff_w() - 2 * RICHTEXT_MARGIN);
 			rt.parse(text_);
 			height = rt.height() + 2 * RICHTEXT_MARGIN;
@@ -143,10 +148,15 @@
  */
 void MultilineTextarea::draw(RenderTarget& dst)
 {
-	if (isrichtext) {
+	if (use_old_renderer_) {
 		rt.draw(dst, Point(RICHTEXT_MARGIN, RICHTEXT_MARGIN - scrollbar_.get_scrollpos()));
 	} else {
-		const Image* text_im = UI::g_fh1->render(make_richtext(), get_eff_w() - 2 * RICHTEXT_MARGIN);
+		const Image* text_im;
+		if (!is_richtext(text_)) {
+			text_im = UI::g_fh1->render(make_richtext(), get_eff_w() - 2 * RICHTEXT_MARGIN);
+		} else {
+			text_im = UI::g_fh1->render(text_, get_eff_w() - 2 * RICHTEXT_MARGIN);
+		}
 
 		uint32_t blit_width = std::min(text_im->width(), static_cast<int>(get_eff_w()));
 		uint32_t blit_height = std::min(text_im->height(), static_cast<int>(get_inner_h()));

=== modified file 'src/ui_basic/multilinetextarea.h'
--- src/ui_basic/multilinetextarea.h	2016-04-01 12:22:09 +0000
+++ src/ui_basic/multilinetextarea.h	2016-04-15 17:37:26 +0000
@@ -58,6 +58,7 @@
 	uint32_t get_eff_w() const {return scrollbar_.is_enabled() ? get_w() - Scrollbar::kSize : get_w();}
 
 	void set_color(RGBColor fg) {color_ = fg;}
+	void force_new_renderer() {force_new_renderer_ = true;}
 
 	// Drawing and event handlers
 	void draw(RenderTarget&) override;
@@ -82,7 +83,8 @@
 	RGBColor color_;
 	Align align_;
 
-	bool isrichtext;
+	bool force_new_renderer_;
+	bool use_old_renderer_;
 	RichText rt;
 
 	Scrollbar   scrollbar_;

=== modified file 'src/ui_fsmenu/launch_mpg.cc'
--- src/ui_fsmenu/launch_mpg.cc	2016-04-05 07:51:48 +0000
+++ src/ui_fsmenu/launch_mpg.cc	2016-04-15 17:37:26 +0000
@@ -234,7 +234,7 @@
 	// Y coordinate will be set later, when we know how high this box will get.
 	suggested_teams_box_ = new UI::SuggestedTeamsBox
 									(this, right_column_x_, 0, UI::Box::Vertical,
-									 padding_, indent_, label_height_,
+									 padding_, indent_,
 									 get_w() - right_column_x_, 4 * label_height_);
 }
 

=== modified file 'src/ui_fsmenu/mapselect.cc'
--- src/ui_fsmenu/mapselect.cc	2016-03-25 17:40:51 +0000
+++ src/ui_fsmenu/mapselect.cc	2016-04-15 17:37:26 +0000
@@ -31,6 +31,7 @@
 #include "logic/game_controller.h"
 #include "logic/game_settings.h"
 #include "map_io/widelands_map_loader.h"
+#include "wui/map_tags.h"
 
 // TODO(GunChleoc): Arabic: line height broken for descriptions for Arabic.
 // Fix align for table headings & entries and for wordwrap.
@@ -94,27 +95,27 @@
 	vbox = new UI::Box(this,
 							 tablex_, vbox->get_y() + vbox->get_h() + padding_,
 							 UI::Box::Horizontal, checkbox_space_, get_w());
-	add_tag_checkbox(vbox, "official", _("Official"));
-	add_tag_checkbox(vbox, "unbalanced", _("Unbalanced"));
-	add_tag_checkbox(vbox, "seafaring", _("Seafaring"));
-	add_tag_checkbox(vbox, "artifacts", _("Artifacts"));
-	add_tag_checkbox(vbox, "scenario", _("Scenario"));
-	vbox->set_size(get_w() - 2 * tablex_, checkbox_space_);
-
-	vbox = new UI::Box(this,
-							 tablex_, vbox->get_y() + vbox->get_h() + padding_,
-							 UI::Box::Horizontal, checkbox_space_, get_w());
-	add_tag_checkbox(vbox, "ffa", _("Free for all"));
-	add_tag_checkbox(vbox, "1v1", _("1v1"));
-
-	vbox->set_size(get_w() - 2 * tablex_, checkbox_space_);
-
-	vbox = new UI::Box(this,
-							 tablex_, vbox->get_y() + vbox->get_h() + padding_,
-							 UI::Box::Horizontal, checkbox_space_, get_w());
-	add_tag_checkbox(vbox, "2teams", _("Teams of 2"));
-	add_tag_checkbox(vbox, "3teams", _("Teams of 3"));
-	add_tag_checkbox(vbox, "4teams", _("Teams of 4"));
+	add_tag_checkbox(vbox, "official", localize_tag("official"));
+	add_tag_checkbox(vbox, "unbalanced", localize_tag("unbalanced"));
+	add_tag_checkbox(vbox, "seafaring", localize_tag("seafaring"));
+	add_tag_checkbox(vbox, "artifacts", localize_tag("artifacts"));
+	add_tag_checkbox(vbox, "scenario", localize_tag("scenario"));
+	vbox->set_size(get_w() - 2 * tablex_, checkbox_space_);
+
+	vbox = new UI::Box(this,
+							 tablex_, vbox->get_y() + vbox->get_h() + padding_,
+							 UI::Box::Horizontal, checkbox_space_, get_w());
+	add_tag_checkbox(vbox, "ffa", localize_tag("ffa"));
+	add_tag_checkbox(vbox, "1v1", localize_tag("1v1"));
+
+	vbox->set_size(get_w() - 2 * tablex_, checkbox_space_);
+
+	vbox = new UI::Box(this,
+							 tablex_, vbox->get_y() + vbox->get_h() + padding_,
+							 UI::Box::Horizontal, checkbox_space_, get_w());
+	add_tag_checkbox(vbox, "2teams", localize_tag("2teams"));
+	add_tag_checkbox(vbox, "3teams", localize_tag("3teams"));
+	add_tag_checkbox(vbox, "4teams", localize_tag("4teams"));
 	vbox->set_size(get_w() - 2 * tablex_, checkbox_space_);
 
 	scenario_types_ = settings_->settings().multiplayer ? Map::MP_SCENARIO : Map::SP_SCENARIO;

=== modified file 'src/wui/CMakeLists.txt'
--- src/wui/CMakeLists.txt	2016-04-02 16:45:53 +0000
+++ src/wui/CMakeLists.txt	2016-04-15 17:37:26 +0000
@@ -63,6 +63,8 @@
     mapdata.h
     maptable.cc
     maptable.h
+    map_tags.cc
+    map_tags.h
     suggested_teams_box.cc
     suggested_teams_box.h
   DEPENDS

=== added file 'src/wui/map_tags.cc'
--- src/wui/map_tags.cc	1970-01-01 00:00:00 +0000
+++ src/wui/map_tags.cc	2016-04-15 17:37:26 +0000
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2016 by the Widelands Development Team
+ *
+ * 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; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include "wui/map_tags.h"
+
+#include "base/i18n.h"
+
+namespace {
+
+const std::map<std::string, std::string> kMapTags = {
+	/** TRANSLATORS: This is a map tag */
+	{"official", _("Official")},
+	/** TRANSLATORS: This is a map tag */
+	{"unbalanced", _("Unbalanced")},
+	/** TRANSLATORS: This is a map tag */
+	{"seafaring", _("Seafaring")},
+	/** TRANSLATORS: This is a map tag */
+	{"artifacts", _("Artifacts")},
+	/** TRANSLATORS: This is a map tag */
+	{"scenario", _("Scenario")},
+	/** TRANSLATORS: This is a map tag */
+	{"ffa", _("Free for all")},
+	/** TRANSLATORS: This is a map tag. One versus one. */
+	{"1v1", _("1v1")},
+	/** TRANSLATORS: This is a map tag */
+	{"2teams", _("Teams of 2")},
+	/** TRANSLATORS: This is a map tag */
+	{"3teams", _("Teams of 3")},
+	/** TRANSLATORS: This is a map tag */
+	{"4teams", _("Teams of 4")},
+};
+
+} // namespace
+
+bool tag_exists(const std::string& tag) {
+	return kMapTags.count(tag) == 1;
+}
+
+const std::string localize_tag(const std::string& tag) {
+	if (tag_exists(tag)) {
+		return _((*kMapTags.find(tag)).second);
+	}
+	return tag;
+}

=== added file 'src/wui/map_tags.h'
--- src/wui/map_tags.h	1970-01-01 00:00:00 +0000
+++ src/wui/map_tags.h	2016-04-15 17:37:26 +0000
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2016 by the Widelands Development Team
+ *
+ * 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; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifndef WL_WUI_MAP_TAGS_H
+#define WL_WUI_MAP_TAGS_H
+
+#include <map>
+#include <string>
+
+/// Functions for localizing the known map tags.
+
+/// Returns true if this tag is known.
+bool tag_exists(const std::string& tag);
+
+/// If tag_exists, returns the localized tag.
+/// Otherwise, returns 'tag'
+const std::string localize_tag(const std::string& tag);
+
+#endif  // end of include guard: WL_WUI_MAP_TAGS_H

=== modified file 'src/wui/mapdetails.cc'
--- src/wui/mapdetails.cc	2016-04-01 18:05:40 +0000
+++ src/wui/mapdetails.cc	2016-04-15 17:37:26 +0000
@@ -18,6 +18,7 @@
 
 #include "wui/mapdetails.h"
 
+#include <algorithm>
 #include <cstdio>
 #include <memory>
 
@@ -33,74 +34,51 @@
 #include "logic/game_settings.h"
 #include "map_io/widelands_map_loader.h"
 #include "ui_basic/box.h"
+#include "wui/map_tags.h"
+
+namespace {
+std::string as_header(const std::string& txt) {
+	return (boost::format("<p><font size=%i bold=1 shadow=1><vspace gap=6>%s</font></p>")
+			  % UI_FONT_SIZE_SMALL
+			  % richtext_escape(txt)).str();
+}
+std::string as_content(const std::string& txt) {
+	return (boost::format("<p><font size=%i shadow=1><vspace gap=2>%s</font></p>")
+			  % UI_FONT_SIZE_SMALL
+			  % richtext_escape(txt)).str();
+}
+} // namespace
 
 MapDetails::MapDetails
-		(Panel* parent, int32_t x, int32_t y, int32_t max_x, int32_t max_y) :
-	UI::Panel(parent, x, y, max_x, max_y),
+		(Panel* parent, int32_t x, int32_t y, int32_t max_w, int32_t max_h) :
+	UI::Panel(parent, x, y, max_w, max_h),
 
 	padding_(4),
-	indent_(10),
-	labelh_(20),
-	max_w_(max_x),
-	max_h_(max_y),
-	// Subtract for main box and author box
-	descr_box_height_(max_y - 4 * labelh_ - 5 * padding_),
-
-	main_box_(this, 0, 0, UI::Box::Vertical,
-		  max_w_, max_h_, 0),
-
-	name_box_(&main_box_, 0, 0, UI::Box::Horizontal,
-		  max_w_, 3 * labelh_ + padding_, padding_ / 2),
-	name_label_(&main_box_, 0, 0, max_w_ - padding_, labelh_, ""),
-	name_(&name_box_, 0, 0, max_w_ - indent_, 2 * labelh_, ""),
-
-	author_box_(&main_box_, 0, 0, UI::Box::Horizontal,
-		  max_w_, 3 * labelh_ + padding_, padding_ / 2),
-	author_label_(&main_box_, 0, 0, max_w_ - padding_, labelh_, ""),
-	author_(&author_box_, 0, 0, max_w_ - indent_, labelh_, ""),
-
-	descr_box_(&main_box_, 0, 0, UI::Box::Horizontal,
-		  max_w_, descr_box_height_, padding_ / 2),
-	descr_label_(&main_box_, 0, 0, max_w_, labelh_, ""),
-	 // -1 to prevent cropping of scrollbar
-	descr_(&descr_box_, 0, 0, max_w_ - indent_ - 1, descr_box_height_ - labelh_ - padding_, "")
+	main_box_(this, 0, 0, UI::Box::Vertical, max_w, max_h, 0),
+	name_label_(&main_box_, 0, 0, max_w - padding_, 20, "", UI::Align::kLeft,
+					UI::MultilineTextarea::ScrollMode::kNoScrolling),
+	descr_(&main_box_, 0, 0, max_w, 20, ""),
+	suggested_teams_box_(new UI::SuggestedTeamsBox(this, 0, 0, UI::Box::Vertical, padding_, 0, max_w))
 {
-	suggested_teams_box_ = new UI::SuggestedTeamsBox(this, 0, 0, UI::Box::Vertical,
-																	 padding_, indent_, labelh_, max_w_, 4 * labelh_);
+	name_label_.force_new_renderer();
+	descr_.force_new_renderer();
 
 	main_box_.add(&name_label_, UI::Align::kLeft);
-	name_box_.add_space(indent_);
-	name_box_.add(&name_, UI::Align::kLeft);
-	main_box_.add(&name_box_, UI::Align::kLeft);
-	main_box_.add_space(padding_);
-
-	main_box_.add(&author_label_, UI::Align::kLeft);
-	author_box_.add_space(indent_);
-	author_box_.add(&author_, UI::Align::kLeft);
-	main_box_.add(&author_box_, UI::Align::kLeft);
-	main_box_.add_space(padding_);
-
-	main_box_.add(&descr_label_, UI::Align::kLeft);
-	descr_box_.add_space(indent_);
-	descr_box_.add(&descr_, UI::Align::kLeft);
-	main_box_.add(&descr_box_, UI::Align::kLeft);
-	main_box_.add_space(padding_);
+	main_box_.add_space(padding_);
+	main_box_.add(&descr_, UI::Align::kLeft);
+	main_box_.set_size(max_w, max_h - name_label_.get_h() - padding_);
+	set_max_height(max_h);
 }
 
 
 void MapDetails::clear() {
 	name_label_.set_text("");
-	author_label_.set_text("");
-	descr_label_.set_text("");
-	name_.set_text("");
-	author_.set_text("");
 	descr_.set_text("");
 	suggested_teams_box_->hide();
 }
 
 void MapDetails::set_max_height(int new_height) {
 	max_h_ = new_height;
-	descr_box_height_ = max_h_ - 4 * labelh_ - 5 * padding_;
 	update_layout();
 }
 
@@ -108,15 +86,11 @@
 	// Adjust sizes for show / hide suggested teams
 	if (suggested_teams_box_->is_visible()) {
 		suggested_teams_box_->set_pos(Point(0, max_h_ - suggested_teams_box_->get_h()));
-		main_box_.set_size(max_w_, max_h_ - suggested_teams_box_->get_h());
-		descr_box_.set_size(
-					descr_box_.get_w(),
-					descr_box_height_ - suggested_teams_box_->get_h() - padding_);
+		main_box_.set_size(main_box_.get_w(), max_h_ - suggested_teams_box_->get_h() - padding_);
 	} else {
-		main_box_.set_size(max_w_, max_h_);
-		descr_box_.set_size(descr_box_.get_w(), descr_box_height_);
+		main_box_.set_size(main_box_.get_w(), max_h_);
 	}
-	descr_.set_size(descr_.get_w(), descr_box_.get_h() - descr_label_.get_h() - padding_);
+	descr_.set_size(descr_.get_w(), main_box_.get_h() - name_label_.get_h() - padding_);
 	descr_.scroll_to_top();
 }
 
@@ -124,42 +98,72 @@
 	clear();
 	if (mapdata.maptype == MapData::MapType::kDirectory) {
 		// Show directory information
-		name_label_.set_text(_("Directory:"));
-		name_.set_text(mapdata.localized_name);
-		name_.set_tooltip(_("The name of this directory"));
-		main_box_.set_size(max_w_, max_h_);
+		name_label_.set_text(as_uifont(mapdata.localized_name, UI_FONT_SIZE_SMALL + 2));
+		descr_.set_text((boost::format("<rt>%s</rt>") % as_header(_("Directory"))).str());
+		main_box_.set_size(main_box_.get_w(), max_h_);
 	} else {
-		// Show map information
-		if (mapdata.maptype == MapData::MapType::kScenario) {
-			name_label_.set_text(_("Scenario:"));
-		} else {
-			name_label_.set_text(_("Map:"));
-		}
-		name_.set_text(localize_mapname ? mapdata.localized_name : mapdata.name);
+		name_label_.set_text(as_uifont(localize_mapname ? mapdata.localized_name : mapdata.name,
+												 UI_FONT_SIZE_SMALL + 2));
+
 		if (mapdata.localized_name != mapdata.name) {
 			if (localize_mapname) {
-				name_.set_tooltip
+				name_label_.set_tooltip
 				/** TRANSLATORS: Tooltip in map description when translated map names are being displayed. */
 				/** TRANSLATORS: %s is the English name of the map. */
 						((boost::format(_("The original name of this map: %s"))
 						  % mapdata.name).str());
 			} else {
-				name_.set_tooltip
+				name_label_.set_tooltip
 				/** TRANSLATORS: Tooltip in map description when map names are being displayed in English. */
 				/** TRANSLATORS: %s is the localized name of the map. */
 						((boost::format(_("The name of this map in your language: %s"))
 						  % mapdata.localized_name).str());
 			}
-		} else {
-			name_.set_tooltip(_("The name of this map"));
-		}
-		author_label_.set_text(ngettext("Author:", "Authors:", mapdata.authors.get_number()));
-		author_.set_text(mapdata.authors.get_names());
-		descr_label_.set_text(_("Description:"));
-		descr_.set_text(
-					mapdata.description +
-					/** TRANSLATORS: Map hint header when selecting a map. */
-					(mapdata.hint.empty() ? "" : (std::string("\n\n") + _("HINT:") + "\n" + mapdata.hint)));
+		}
+
+		// Show map information
+		std::string description =
+				as_header(
+					mapdata.maptype == MapData::MapType::kScenario ?
+						(boost::format(ngettext("%d Player Scenario", "%d Player Scenario", mapdata.nrplayers))
+						%  mapdata.nrplayers).str()  :
+						(boost::format(ngettext("%d Player Map", "%d Player Map", mapdata.nrplayers))
+						%  mapdata.nrplayers).str());
+
+		description = (boost::format("%s%s")
+							  % description
+							  % as_header(ngettext("Author", "Authors", mapdata.authors.get_number()))).str();
+		description = (boost::format("%s%s") % description % as_content(mapdata.authors.get_names())).str();
+
+		description = (boost::format("%s%s") % description % as_header(_("Map Size"))).str();
+		description = (boost::format("%s%s")
+							% description
+							% as_content((boost::format(_("%d × %d"))
+											  % mapdata.width
+											  % mapdata.height).str())).str();
+
+		std::vector<std::string> tags;
+		for (const auto& tag : mapdata.tags) {
+			tags.push_back(localize_tag(tag));
+		}
+		std::sort(tags.begin(), tags.end());
+		description = (boost::format("%s%s") % description % as_header(_("Tags"))).str();
+		description = (boost::format("%s%s")
+							% description %
+							as_content(i18n::localize_list(tags, i18n::ConcatenateWith::COMMA)))
+						  .str();
+
+		description = (boost::format("%s%s") % description % as_header(_("Description"))).str();
+		description = (boost::format("%s%s") % description % as_content(mapdata.description)).str();
+
+		if (!mapdata.hint.empty()) {
+			/** TRANSLATORS: Map hint header when selecting a map. */
+			description = (boost::format("%s%s") % description % as_header(_("Hint"))).str();
+			description = (boost::format("%s%s") % description % as_content(mapdata.hint)).str();
+		}
+
+		description = (boost::format("<rt>%s</rt>") % description).str();
+		descr_.set_text(description);
 
 		// Show / hide suggested teams
 		if (mapdata.suggested_teams.empty()) {

=== modified file 'src/wui/mapdetails.h'
--- src/wui/mapdetails.h	2016-03-23 08:47:27 +0000
+++ src/wui/mapdetails.h	2016-04-15 17:37:26 +0000
@@ -23,7 +23,6 @@
 #include "ui_basic/box.h"
 #include "ui_basic/multilinetextarea.h"
 #include "ui_basic/panel.h"
-#include "ui_basic/textarea.h"
 #include "wui/mapdata.h"
 #include "wui/suggested_teams_box.h"
 
@@ -33,9 +32,7 @@
  */
 class MapDetails : public UI::Panel {
 public:
-	MapDetails(Panel * parent,
-				  int32_t x, int32_t y,
-				  int32_t max_x, int32_t max_y);
+	MapDetails(Panel* parent, int32_t x, int32_t y, int32_t max_w, int32_t max_h);
 
 	void clear();
 	void set_max_height(int new_height);
@@ -43,23 +40,12 @@
 	void update(const MapData& mapdata, bool localize_mapname);
 
 private:
-	const int padding_, indent_, labelh_, max_w_;
-	int max_h_, descr_box_height_;
+	const int padding_;
+	int max_h_;
 
 	UI::Box main_box_;
-
-	UI::Box name_box_;
-	UI::Textarea name_label_;
-	UI::MultilineTextarea name_;
-
-	UI::Box author_box_;
-	UI::Textarea author_label_;
-	UI::MultilineTextarea author_;
-
-	UI::Box descr_box_;
-	UI::Textarea descr_label_;
+	UI::MultilineTextarea name_label_;
 	UI::MultilineTextarea descr_;
-
 	UI::SuggestedTeamsBox* suggested_teams_box_;
 };
 

=== modified file 'src/wui/suggested_teams_box.cc'
--- src/wui/suggested_teams_box.cc	2016-02-10 20:39:02 +0000
+++ src/wui/suggested_teams_box.cc	2016-04-15 17:37:26 +0000
@@ -42,13 +42,12 @@
 SuggestedTeamsBox::SuggestedTeamsBox(Panel * parent,
 							int32_t x, int32_t y,
 							uint32_t orientation,
-							int32_t padding, int32_t indent, int32_t label_height,
-							int32_t max_x, int32_t max_y,
-							uint32_t inner_spacing) :
-	UI::Box(parent, x, y, orientation, max_x, max_y, inner_spacing),
+							int32_t padding, int32_t indent,
+							int32_t max_x, int32_t max_y) :
+	UI::Box(parent, x, y, orientation, max_x, max_y, g_gr->images().get(player_pictures_small[0])->height()),
 	padding_(padding),
 	indent_(indent),
-	label_height_(label_height)
+	label_height_(g_gr->images().get(player_pictures_small[0])->height() + padding)
 {
 	player_icons_.clear();
 	suggested_teams_.clear();
@@ -105,10 +104,10 @@
 		for (const Widelands::Map::SuggestedTeamLineup& lineup : suggested_teams_) {
 
 			lineup_box_ =
-					new UI::Box(this, indent_, teamlist_offset + lineup_counter * (label_height_ + padding_),
+					new UI::Box(this, indent_, teamlist_offset + lineup_counter * (label_height_),
 									UI::Box::Horizontal, get_w() - indent_);
 
-			lineup_box_->set_size(get_w(), label_height_ + padding_);
+			lineup_box_->set_size(get_w(), label_height_);
 
 			bool is_first = true;
 			for (const Widelands::Map::SuggestedTeam& team : lineup) {
@@ -127,7 +126,8 @@
 					assert(player < MAX_PLAYERS);
 					const Image* player_image = g_gr->images().get(player_pictures_small[player]);
 					assert(player_image);
-					player_icon = new UI::Icon(lineup_box_, 0, 0, 20, 20, player_image);
+					player_icon = new UI::Icon(lineup_box_, 0, 0,
+														player_image->width(), player_image->height(), player_image);
 					player_icon->set_visible(true);
 					player_icon->set_no_frame();
 					lineup_box_->add(player_icon, UI::Align::kLeft);
@@ -138,7 +138,7 @@
 		} // All lineups
 
 		// Adjust size to content
-		set_size(get_w(), teamlist_offset + lineup_counter * (label_height_ + padding_));
+		set_size(get_w(), teamlist_offset + lineup_counter * (label_height_));
 	}
 }
 

=== modified file 'src/wui/suggested_teams_box.h'
--- src/wui/suggested_teams_box.h	2016-01-24 20:11:53 +0000
+++ src/wui/suggested_teams_box.h	2016-04-15 17:37:26 +0000
@@ -36,9 +36,8 @@
 	SuggestedTeamsBox(Panel * parent,
 							int32_t x, int32_t y,
 							uint32_t orientation,
-							int32_t padding, int32_t indent, int32_t label_height,
-							int32_t max_x = 0, int32_t max_y = 0,
-							uint32_t inner_spacing = 0);
+							int32_t padding, int32_t indent,
+							int32_t max_x = 0, int32_t max_y = 0);
 	~SuggestedTeamsBox();
 
 	void hide();


Follow ups