← Back to team overview

widelands-dev team mailing list archive

[Merge] lp:~widelands-dev/widelands/text-overlays into lp:widelands

 

GunChleoc has proposed merging lp:~widelands-dev/widelands/text-overlays into lp:widelands.

Commit message:
Fixed overlapping building names and long window titles:
- All text overlays now use the condensed font
- Long building names will automatically wrap into multiple lines
- Windows also resize their titles to fit.
- Moved FPS overlay to top center and removed it from the editor.
- Some code cleanup.

Requested reviews:
  Widelands Developers (widelands-dev)
Related bugs:
  Bug #1216523 in widelands: "overlapping text (building names)"
  https://bugs.launchpad.net/widelands/+bug/1216523

For more details, see:
https://code.launchpad.net/~widelands-dev/widelands/text-overlays/+merge/287754

Fixed overlapping building names and long window titles. The UI design has been approved on the forum.

Screenshot: https://wl.widelands.org/forum/topic/1939/?page=2#post-16590
-- 
Your team Widelands Developers is requested to review the proposed merge of lp:~widelands-dev/widelands/text-overlays into lp:widelands.
=== modified file 'src/graphic/text_layout.cc'
--- src/graphic/text_layout.cc	2016-02-18 09:29:38 +0000
+++ src/graphic/text_layout.cc	2016-03-02 09:23:51 +0000
@@ -63,18 +63,14 @@
 	return f.str();
 }
 
-std::string as_window_title(const std::string& txt) {
-	static boost::format f("<rt><p><font face=sans size=13 bold=1 color=%s>%s</font></p></rt>");
-
-	f % UI_FONT_CLR_FG.hex_value();
-	f % txt;
-	return f.str();
-}
-
 std::string as_uifont(const std::string & txt, int size, const RGBColor& clr, UI::FontSet::Face face) {
 	return as_aligned(txt, UI::Align::kLeft, size, clr, face);
 }
 
+std::string as_condensed(const std::string& text, UI::Align align, int ptsize, const RGBColor& clr) {
+	return as_aligned(text, align, ptsize, clr, UI::FontSet::Face::kCondensed);
+}
+
 std::string as_editorfont(const std::string& text, int ptsize, const RGBColor& clr) {
 	// UI Text is always bold due to historic reasons
 	static boost::format
@@ -138,10 +134,10 @@
 
 const Image* autofit_ui_text(const std::string& text, int width, RGBColor color, int fontsize) {
 	const Image* result =
-	   UI::g_fh1->render(as_uifont(text, fontsize, color, UI::FontSet::Face::kSans));
+		UI::g_fh1->render(as_uifont(text, fontsize, color));
 	if (width > 0) { // Autofit
 		for (; result->width() > width && fontsize >= kMinimumFontSize; --fontsize) {
-			result = UI::g_fh1->render(as_uifont(text, fontsize, color, UI::FontSet::Face::kCondensed));
+			result = UI::g_fh1->render(as_condensed(text, UI::Align::kLeft, fontsize, color));
 		}
 	}
 	return result;

=== modified file 'src/graphic/text_layout.h'
--- src/graphic/text_layout.h	2016-02-13 11:04:05 +0000
+++ src/graphic/text_layout.h	2016-03-02 09:23:51 +0000
@@ -70,6 +70,10 @@
 	(const std::string&, int ptsize = UI_FONT_SIZE_SMALL, const RGBColor& clr = UI_FONT_CLR_FG,
 	 UI::FontSet::Face face = UI::FontSet::Face::kSans);
 
+// Same as as_aligned, but with the condensed font preselected.
+std::string as_condensed
+	(const std::string& text, UI::Align align = UI::Align::kLeft, int ptsize = UI_FONT_SIZE_SMALL, const RGBColor& clr = UI_FONT_CLR_FG);
+
 std::string as_editorfont(const std::string& text, int ptsize = UI_FONT_SIZE_SMALL,
 								  const RGBColor& clr = UI_FONT_CLR_FG);
 
@@ -79,7 +83,6 @@
 
 std::string as_tooltip(const std::string&);
 std::string as_waresinfo(const std::string&);
-std::string as_window_title(const std::string&);
 std::string as_game_tip(const std::string&);
 
 /**

=== modified file 'src/logic/map_objects/tribes/building.cc'
--- src/logic/map_objects/tribes/building.cc	2016-02-15 22:31:59 +0000
+++ src/logic/map_objects/tribes/building.cc	2016-03-02 09:23:51 +0000
@@ -502,7 +502,7 @@
 	default:
 		NEVER_HERE();
 	}
-	return result.empty() ? result : as_uifont(result);
+	return result;
 }
 
 
@@ -671,22 +671,29 @@
 		dynamic_cast<const InteractiveGameBase&>(*game.get_ibase());
 	uint32_t const dpyflags = igbase.get_display_flags();
 
-	if (dpyflags & InteractiveBase::dfShowCensus) {
-		const std::string info = info_string(InfoStringFormat::kCensus);
-		if (!info.empty()) {
-			dst.blit(pos - Point(0, 48), UI::g_fh1->render(info), BlendMode::UseAlpha, UI::Align::kCenter);
+	if (dpyflags & InteractiveBase::dfShowCensus || dpyflags & InteractiveBase::dfShowStatistics) {
+		// We always render this so we can have a stable position for the statistics string.
+		const Image* rendered_census_info =
+				UI::g_fh1->render(as_condensed(info_string(InfoStringFormat::kCensus), UI::Align::kCenter),
+										120);
+		const Point census_pos(pos - Point(0, 48));
+
+		if (dpyflags & InteractiveBase::dfShowCensus) {
+			dst.blit(census_pos, rendered_census_info, BlendMode::UseAlpha, UI::Align::kCenter);
 		}
-	}
 
-	if (dpyflags & InteractiveBase::dfShowStatistics) {
-		if (upcast(InteractivePlayer const, iplayer, &igbase))
-			if
-				(!iplayer->player().see_all() &&
-				 iplayer->player().is_hostile(*get_owner()))
-				return;
-		const std::string info = info_string(InfoStringFormat::kStatistics);
-		if (!info.empty()) {
-			dst.blit(pos - Point(0, 35), UI::g_fh1->render(info), BlendMode::UseAlpha, UI::Align::kCenter);
+		if (dpyflags & InteractiveBase::dfShowStatistics) {
+			if (upcast(InteractivePlayer const, iplayer, &igbase))
+				if
+					(!iplayer->player().see_all() &&
+					 iplayer->player().is_hostile(*get_owner()))
+					return;
+			const std::string& info = info_string(InfoStringFormat::kStatistics);
+			if (!info.empty()) {
+				dst.blit(census_pos + Point(0, rendered_census_info->height() / 2 + 10),
+							UI::g_fh1->render(as_condensed(info)),
+							BlendMode::UseAlpha, UI::Align::kCenter);
+			}
 		}
 	}
 }

=== modified file 'src/logic/map_objects/tribes/militarysite.cc'
--- src/logic/map_objects/tribes/militarysite.cc	2016-02-13 12:15:29 +0000
+++ src/logic/map_objects/tribes/militarysite.cc	2016-03-02 09:23:51 +0000
@@ -30,6 +30,7 @@
 #include "base/macros.h"
 #include "economy/flag.h"
 #include "economy/request.h"
+#include "graphic/text_constants.h"
 #include "logic/editor_game_base.h"
 #include "logic/findbob.h"
 #include "logic/game.h"
@@ -123,12 +124,12 @@
 		if (capacity_ > stationed) {
 			/** TRANSLATORS: %1% is the number of soldiers the plural refers to */
 			/** TRANSLATORS: %2% is the maximum number of soldier slots in the building */
-			*s += (boost::format(ngettext("%1% soldier (+%2%)",
+			*s = (boost::format(ngettext("%1% soldier (+%2%)",
 																		  "%1% soldiers (+%2%)",
 																		  stationed))
 											% stationed % (capacity_ - stationed)).str();
 		} else {
-			*s += (boost::format(ngettext("%u soldier", "%u soldiers", stationed))
+			*s = (boost::format(ngettext("%u soldier", "%u soldiers", stationed))
 											% stationed).str();
 		}
 	} else {
@@ -142,10 +143,12 @@
 		} else {
 			/** TRANSLATORS: %1% is the number of soldiers the plural refers to */
 			/** TRANSLATORS: %2% are currently open soldier slots in the building */
-			*s += (boost::format(ngettext("%1%(+%2%) soldier", "%1%(+%2%) soldiers", stationed))
+			*s = (boost::format(ngettext("%1%(+%2%) soldier", "%1%(+%2%) soldiers", stationed))
 					% present % (stationed - present)).str();
 		}
 	}
+	*s = (boost::format("<font color=%s>%s</font>") % UI_FONT_CLR_OK.hex_value() % *s).str();
+
 }
 
 

=== modified file 'src/logic/map_objects/tribes/productionsite.cc'
--- src/logic/map_objects/tribes/productionsite.cc	2016-02-20 12:23:07 +0000
+++ src/logic/map_objects/tribes/productionsite.cc	2016-03-02 09:23:51 +0000
@@ -401,7 +401,7 @@
 
 	if (0 < percOk && percOk < 100) {
 		// TODO(GunChleoc): We might need to reverse the order here for RTL languages
-		statistics_string_on_changed_statistics_ = (boost::format("%s %s") % perc_str % trend_str).str();
+		statistics_string_on_changed_statistics_ = (boost::format("%s\u2009%s") % perc_str % trend_str).str();
 	} else {
 		statistics_string_on_changed_statistics_ = perc_str;
 	}

=== modified file 'src/ui_basic/table.cc'
--- src/ui_basic/table.cc	2016-02-09 16:29:48 +0000
+++ src/ui_basic/table.cc	2016-03-02 09:23:51 +0000
@@ -51,9 +51,8 @@
 :
 	Panel             (parent, x, y, w, h),
 	total_width_     (0),
-	fontsize_        (UI_FONT_SIZE_SMALL),
-	headerheight_    (UI::g_fh1->render(as_uifont(".", fontsize_))->height() + 4),
-	lineheight_      (UI::g_fh1->render(as_uifont(".", fontsize_))->height()),
+	headerheight_    (UI::g_fh1->render(as_uifont("."))->height() + 4),
+	lineheight_      (UI::g_fh1->render(as_uifont("."))->height()),
 	scrollbar_       (nullptr),
 	scrollpos_       (0),
 	selection_       (no_selection_index()),
@@ -347,7 +346,7 @@
 				curx += curw;
 				continue;
 			}
-			const Image* entry_text_im = UI::g_fh1->render(as_uifont(richtext_escape(entry_string), fontsize_));
+			const Image* entry_text_im = UI::g_fh1->render(as_uifont(richtext_escape(entry_string)));
 
 			if (static_cast<int>(alignment & UI::Align::kRight)) {
 				point.x += curw - 2 * picw;

=== modified file 'src/ui_basic/table.h'
--- src/ui_basic/table.h	2016-02-09 16:29:48 +0000
+++ src/ui_basic/table.h	2016-03-02 09:23:51 +0000
@@ -270,7 +270,6 @@
 
 	Columns            columns_;
 	uint32_t           total_width_;
-	uint32_t           fontsize_;
 	uint32_t           headerheight_;
 	int32_t            lineheight_;
 	Scrollbar        * scrollbar_;

=== modified file 'src/ui_basic/window.cc'
--- src/ui_basic/window.cc	2016-02-09 16:29:48 +0000
+++ src/ui_basic/window.cc	2016-03-02 09:23:51 +0000
@@ -109,7 +109,8 @@
 */
 void Window::set_title(const string & text)
 {
-	title_ = is_richtext(text) ? text : as_window_title(text);
+	assert(!is_richtext(text));
+	title_ = text;
 }
 
 /**
@@ -312,9 +313,10 @@
 
 	// draw the title if we have one
 	if (!title_.empty()) {
+		// The title shouldn't be richtext, but we escape it just to make sure.
 		dst.blit
 			(Point(get_lborder() + get_inner_w() / 2, TP_B_PIXMAP_THICKNESS / 2),
-				UI::g_fh1->render(title_),
+			 autofit_ui_text(richtext_escape(title_), get_inner_w(), UI_FONT_CLR_FG, 13),
 				BlendMode::UseAlpha,
 				UI::Align::kCenter);
 	}

=== modified file 'src/ui_basic/window.h'
--- src/ui_basic/window.h	2016-02-09 16:29:48 +0000
+++ src/ui_basic/window.h	2016-03-02 09:23:51 +0000
@@ -52,6 +52,7 @@
  */
 class Window : public NamedPanel {
 public:
+	/// Do not use richtext for the \param title.
 	Window
 		(Panel      * parent,
 		 const std::string& name,
@@ -61,7 +62,8 @@
 		 uint32_t     h,
 		 const std::string& title);
 
-	void set_title(const std::string &);
+	/// This will set the window title. Do not use richtext for the \param text.
+	void set_title(const std::string& text);
 	const std::string & get_title() const {return title_;}
 
 	void set_center_panel(Panel * panel);

=== modified file 'src/wui/interactive_base.cc'
--- src/wui/interactive_base.cc	2016-02-13 19:17:06 +0000
+++ src/wui/interactive_base.cc	2016-03-02 09:23:51 +0000
@@ -356,17 +356,17 @@
 		std::string node_text;
 		if (is_game) {
 			const std::string gametime(gametimestring(egbase().get_gametime(), true));
-			const std::string gametime_text = as_uifont(gametime, UI_FONT_SIZE_SMALL);
+			const std::string gametime_text = as_condensed(gametime);
 			dst.blit(Point(5, 5), UI::g_fh1->render(gametime_text), BlendMode::UseAlpha, UI::Align::kTopLeft);
 
 			static boost::format node_format("(%i, %i)");
-			node_text = as_uifont
-				((node_format % sel_.pos.node.x % sel_.pos.node.y).str(), UI_FONT_SIZE_SMALL);
+			node_text = as_condensed
+				((node_format % sel_.pos.node.x % sel_.pos.node.y).str());
 		} else { //this is an editor
 			static boost::format node_format("(%i, %i, %i)");
 			const int32_t height = map[sel_.pos.node].get_height();
-			node_text = as_uifont
-				((node_format % sel_.pos.node.x % sel_.pos.node.y % height).str(), UI_FONT_SIZE_SMALL);
+			node_text = as_condensed
+				((node_format % sel_.pos.node.x % sel_.pos.node.y % height).str());
 		}
 
 		dst.blit(
@@ -376,14 +376,13 @@
 			UI::Align::kBottomRight);
 	}
 
-	// Blit FPS when in debug mode.
-	if (get_display_flag(dfDebug)) {
+	// Blit FPS when playing a game in debug mode.
+	if (get_display_flag(dfDebug) && is_game) {
 		static boost::format fps_format("%5.1f fps (avg: %5.1f fps)");
-		const std::string fps_text = as_uifont(
-		   (fps_format % (1000.0 / frametime_) % (1000.0 / (avg_usframetime_ / 1000))).str(),
-		   UI_FONT_SIZE_SMALL);
-		dst.blit(Point(5, (is_game) ? 25 : 5),
-		         UI::g_fh1->render(fps_text),
+		const Image * rendered_text = UI::g_fh1->render(as_condensed(
+			(fps_format % (1000.0 / frametime_) % (1000.0 / (avg_usframetime_ / 1000))).str()));
+		dst.blit(Point((get_w() - rendered_text->width()) / 2, 5),
+					rendered_text,
 		         BlendMode::UseAlpha,
 					UI::Align::kLeft);
 	}

=== modified file 'src/wui/interactive_gamebase.cc'
--- src/wui/interactive_gamebase.cc	2016-02-09 16:29:48 +0000
+++ src/wui/interactive_gamebase.cc	2016-03-02 09:23:51 +0000
@@ -103,14 +103,13 @@
 		uint32_t const desired = game_controller->desired_speed();
 		if (real == desired) {
 			if (real != 1000) {
-				game_speed = as_uifont(speed_string(real), UI_FONT_SIZE_SMALL);
+				game_speed = as_condensed(speed_string(real));
 			}
 		} else {
-			game_speed = as_uifont((boost::format
+			game_speed = as_condensed((boost::format
 											/** TRANSLATORS: actual_speed (desired_speed) */
 											(_("%1$s (%2$s)")) %
-											speed_string(real) % speed_string(desired)).str(),
-										  UI_FONT_SIZE_SMALL);
+											speed_string(real) % speed_string(desired)).str());
 		}
 
 		if (!game_speed.empty()) {


Follow ups