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

Proposed by GunChleoc
Status: Merged
Merged at revision: 7990
Proposed branch: lp:~widelands-dev/widelands/revise-map-descr
Merge into: lp:widelands
Diff against target: 788 lines (+281/-159)
16 files modified
src/editor/ui_menus/main_menu_load_or_save_map.cc (+2/-1)
src/editor/ui_menus/main_menu_map_options.cc (+7/-6)
src/graphic/text/rt_parse.cc (+1/-0)
src/ui_basic/multilinetextarea.cc (+20/-12)
src/ui_basic/multilinetextarea.h (+3/-1)
src/ui_basic/scrollbar.cc (+3/-0)
src/ui_fsmenu/launch_mpg.cc (+1/-1)
src/ui_fsmenu/mapselect.cc (+23/-22)
src/wui/CMakeLists.txt (+2/-0)
src/wui/map_tags.cc (+60/-0)
src/wui/map_tags.h (+35/-0)
src/wui/mapdata.cc (+4/-3)
src/wui/mapdetails.cc (+99/-83)
src/wui/mapdetails.h (+10/-18)
src/wui/suggested_teams_box.cc (+9/-9)
src/wui/suggested_teams_box.h (+2/-3)
To merge this branch: bzr merge lp:~widelands-dev/widelands/revise-map-descr
Reviewer Review Type Date Requested Status
Miroslav Remák code Approve
kaputtnik (community) testing Approve
Review via email: mp+292031@code.launchpad.net

Commit message

Revised map details in map loading screens. Localized map tags everywhere.

Description of the change

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.

To post a comment you must log in.
Revision history for this message
kaputtnik (franku) wrote :

Good ideas :-)

Some things:
1. The slider of the scrollbar does not change his size if there is less to scroll (the slider is always small) Good to see in screen resolution 1280x720 and map Four Mountains.
2. There are obsolete information: "Map size" and "2/3/4/... Player map". These information is always in the table, so why should we have it in the description again?
3. Having non bold text for normal descriptions is fine, but for me it is hard to read in the first time. Maybe we could have another color for the text or a different background?

Showing the tags is a good idea :-)

Just a side note:
For a longer time i thought of a rework of the menus (especially in regard to my point 3), but i had no good ideas until today... and of course i do not know which possibilities there are. F.e. the checkboxes in "New game" looks a bit unordered and i guess some of them aren't used at all. Maybe we could make a poll on the website to determine what is really needed here. But creating a good, useful ui is a long and not easy task ... So nothing against your work :-)

Revision history for this message
bunnybot (widelandsofficial) wrote :

Continuous integration builds have changed state:

Travis build 1016. State: failed. Details: https://travis-ci.org/widelands/widelands/builds/123413309.
Appveyor build 848. State: success. Details: https://ci.appveyor.com/project/widelands-dev/widelands/build/_widelands_dev_widelands_revise_map_descr-848.

Revision history for this message
GunChleoc (gunchleoc) wrote :

1. Fixed

> 2. There are obsolete information: "Map size" and "2/3/4/... Player map".
> These information is always in the table, so why should we have it in the
> description again?

We also use this in Editor-> Save Map. Do you think the information is useless there as well? There are 3 ways we could go:

a. leave the info in
b. remove the info
c. distinguish between loading and saving contexts

3. How is it now?

> Just a side note:

Good idea, but not for Build 19 ;)

Revision history for this message
kaputtnik (franku) wrote :

Got a crash when trying to access a folder in 'editor load map' and 'New game':

terminate called after throwing an instance of 'RT::SyntaxErrorImpl'
  what(): Syntax error at 1:65: expected an allowed tag, got 'parent'. String continues with: '<parent></font></p></rt>'

> 1. Fixed
Yeah :-)

> > 2. There are obsolete information: "Map size" and "2/3/4/... Player map".
> > These information is always in the table, so why should we have it in the
> > description again?
>
> We also use this in Editor-> Save Map. Do you think the information is useless
> there as well?
Yes, i think so. A mapmaker normally knows how much players he has placed on the map. The size of the map is mostly interesting when creating a new map because it has influence to max. number of players or shaping the terrain (how much unbuildable areas). And if a map is saved once, the size is shown in table. The size of the map is also shown in the Map options menu and as explained earlier i would prefer to make the Map Options be a part of the whole Map save process (i create a bug report for this idea).
So i would say:

> b. remove the info

> 3. How is it now?
Hm, maybe better but now there is a mix of coloring headers: Mapname, yellow; String "Author", white; Name of author yellow. If we think of Headers as static strings (Name of map, "Author", "Tags"...) and other texts as variable strings (Name of Author, List of tags, Text of description,...) i think all static texts should have the same color (f.e. yellow) and all variable texts should have the same color (f.e. white). The Name of the menu is also a static text and therefor should have the same color as other static texts. I believe making a distinction like this (static/variable texts) would bring some visual order to the menu. Having two colors is really good :-)

> > Just a side note:
>
> Good idea, but not for Build 19 ;)

Yes, of course ;)

Revision history for this message
bunnybot (widelandsofficial) wrote :

Continuous integration builds have changed state:

Travis build 1018. State: passed. Details: https://travis-ci.org/widelands/widelands/builds/123520813.
Appveyor build 850. State: success. Details: https://ci.appveyor.com/project/widelands-dev/widelands/build/_widelands_dev_widelands_revise_map_descr-850.

Revision history for this message
GunChleoc (gunchleoc) wrote :

> b. remove the info

Done

3. A consistent color scheme is always good, but I don't think we can pull this off easily without doing a bigger overhaul. The colors have to fit for both dark and light backgrounds. So, I have removed the color from the headers and used some italic texts instead. How does it look to you now?

Revision history for this message
kaputtnik (franku) wrote :

Hm, i don't know really. The two colored texts are better in my opinion. I have made some screenshots for a comparison and changed the code to use the bright gray color for "txt as_content": http://home.arcor.de/frank.ue/menu_shots.jpg

Above left: Current trunk
Above right: This branch with italic
Middle left: Bright gray for "as_content"
Middle right: For comparison of bright gray with wooden background
Bottom: Load save game menu

I believe the main problematic thing is to visual distinguish between headers and the text. Currently this is made by having a colon after each header and indentation of content texts, which i like very much. Regarding the colon: "Suggested Teams" has it, and putting it after the other headers would help to distinguish, IMHO.

One other thing is disturbing: The second line. This shows either "Map", "Scenario" or "Directory" after the Name of the map/directory. The second line is not "self explaining". If one chooses different maps from the list there is always "Map" shown. So he/she may ask him/her self what does this "Map" mean? In current trunk this is better solved by having the strings "Map:", "Scenario:" and "Directory:" (with colon) as first line and the second line contains then the name of the map or the name of directory. This explains the second line instead in this branch there is no explaining.

I think the main problem for doing this branch is the suggested teams area, which needs a lot of space. Maybe we find another solution for this issue later on. F.e i could imagine to place suggested teams in the Launch Game menu... Just because it is then shown when the teams could be made. Currently the suggested teams could not be seen anymore where one has to make them. Future talk...

Revision history for this message
GunChleoc (gunchleoc) wrote :

How is it now? We can't do indents at this time, so I'm using a color scheme again. I made separate layouts for the fullscreen and the editor menus.

Revision history for this message
bunnybot (widelandsofficial) wrote :

Continuous integration builds have changed state:

Travis build 1025. State: failed. Details: https://travis-ci.org/widelands/widelands/builds/124406264.
Appveyor build 857. State: success. Details: https://ci.appveyor.com/project/widelands-dev/widelands/build/_widelands_dev_widelands_revise_map_descr-857.

Revision history for this message
kaputtnik (franku) wrote :

I think it's good now... maybe decrease the font size a bit in the load game menu?

There is now different coloring for headers in editor and load game, but the color scheme in editor is the same as for the help, so there is a consistent coloring "white headers on wooden background".

But my opinion is not the only valid one. Maybe someone else should tell his opinion? Asking in forum?

No crash discovered :-)

review: Approve (testing)
Revision history for this message
GunChleoc (gunchleoc) wrote :

Decreasing the font size makes it harder to read, so I'd rather not.

Revision history for this message
Miroslav Remák (miroslavr256) wrote :

Codecheck complains:
src/wui/mapdetails.cc:153: Line is too long! Keep it < 110 chars (with tab width of 3)

LGTM otherwise.

review: Approve (code)
Revision history for this message
bunnybot (widelandsofficial) wrote :

Bunnybot encountered an error while working on this merge proposal:

The read operation timed out

Revision history for this message
bunnybot (widelandsofficial) wrote :

Continuous integration builds have changed state:

Travis build 1025. State: failed. Details: https://travis-ci.org/widelands/widelands/builds/124406264.
Appveyor build 857. State: success. Details: https://ci.appveyor.com/project/widelands-dev/widelands/build/_widelands_dev_widelands_revise_map_descr-857.

Revision history for this message
GunChleoc (gunchleoc) wrote :

Thanks!

@bunnybot merge

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/editor/ui_menus/main_menu_load_or_save_map.cc'
2--- src/editor/ui_menus/main_menu_load_or_save_map.cc 2016-04-06 09:23:04 +0000
3+++ src/editor/ui_menus/main_menu_load_or_save_map.cc 2016-05-06 08:30:33 +0000
4@@ -48,7 +48,8 @@
5
6 table_(this, tablex_, tabley_, tablew_, tableh_, false),
7 map_details_(
8- this, right_column_x_, tabley_, get_inner_w() - right_column_x_ - padding_, tableh_),
9+ this, right_column_x_, tabley_, get_inner_w() - right_column_x_ - padding_, tableh_,
10+ MapDetails::Style::kWui),
11 ok_(this,
12 "ok",
13 UI::g_fh1->fontset()->is_rtl() ? get_inner_w() / 2 - butw_ - padding_ : get_inner_w() / 2 + padding_,
14
15=== modified file 'src/editor/ui_menus/main_menu_map_options.cc'
16--- src/editor/ui_menus/main_menu_map_options.cc 2016-04-23 13:33:53 +0000
17+++ src/editor/ui_menus/main_menu_map_options.cc 2016-05-06 08:30:33 +0000
18@@ -33,6 +33,7 @@
19 #include "ui_basic/multilineeditbox.h"
20 #include "ui_basic/multilinetextarea.h"
21 #include "ui_basic/textarea.h"
22+#include "wui/map_tags.h"
23
24 inline EditorInteractive & MainMenuMapOptions::eia() {
25 return dynamic_cast<EditorInteractive&>(*get_parent());
26@@ -122,12 +123,12 @@
27
28
29 tags_box_.add(new UI::Textarea(&tags_box_, 0, 0, max_w_, labelh_, _("Tags:")), UI::Align::kLeft);
30- add_tag_checkbox(&tags_box_, "unbalanced", _("Unbalanced"));
31- add_tag_checkbox(&tags_box_, "ffa", _("Free for all"));
32- add_tag_checkbox(&tags_box_, "1v1", _("1v1"));
33- add_tag_checkbox(&tags_box_, "2teams", _("Teams of 2"));
34- add_tag_checkbox(&tags_box_, "3teams", _("Teams of 3"));
35- add_tag_checkbox(&tags_box_, "4teams", _("Teams of 4"));
36+ add_tag_checkbox(&tags_box_, "unbalanced", localize_tag("unbalanced"));
37+ add_tag_checkbox(&tags_box_, "ffa", localize_tag("ffa"));
38+ add_tag_checkbox(&tags_box_, "1v1", localize_tag("1v1"));
39+ add_tag_checkbox(&tags_box_, "2teams", localize_tag("2teams"));
40+ add_tag_checkbox(&tags_box_, "3teams", localize_tag("3teams"));
41+ add_tag_checkbox(&tags_box_, "4teams", localize_tag("4teams"));
42
43 teams_box_.add(new UI::Textarea(&teams_box_, 0, 0, max_w_, labelh_, _("Suggested Teams:")),
44 UI::Align::kLeft);
45
46=== modified file 'src/graphic/text/rt_parse.cc'
47--- src/graphic/text/rt_parse.cc 2016-03-14 19:49:52 +0000
48+++ src/graphic/text/rt_parse.cc 2016-05-06 08:30:33 +0000
49@@ -274,6 +274,7 @@
50
51 tc.allowed_children.insert("br");
52 tc.allowed_children.insert("space");
53+ tc.allowed_children.insert("vspace");
54 tc.allowed_children.insert("p");
55 tc.allowed_children.insert("font");
56 tc.allowed_children.insert("sub");
57
58=== modified file 'src/ui_basic/multilinetextarea.cc'
59--- src/ui_basic/multilinetextarea.cc 2016-04-01 09:29:17 +0000
60+++ src/ui_basic/multilinetextarea.cc 2016-05-06 08:30:33 +0000
61@@ -41,7 +41,8 @@
62 Panel (parent, x, y, w, h),
63 text_ (text),
64 color_(UI_FONT_CLR_FG),
65- isrichtext(false),
66+ force_new_renderer_(false),
67+ use_old_renderer_(false),
68 scrollbar_ (this, get_w() - Scrollbar::kSize, 0, Scrollbar::kSize, h, false),
69 scrollmode_(scroll_mode)
70 {
71@@ -56,14 +57,11 @@
72 scrollbar_.set_singlestepsize(UI::g_fh1->render(as_uifont(
73 UI::g_fh1->fontset()->representative_character(),
74 UI_FONT_SIZE_SMALL))->height());
75- scrollbar_.set_pagesize(h - 2 * UI::g_fh1->render(as_uifont(
76- UI::g_fh1->fontset()->representative_character(),
77- UI_FONT_SIZE_BIG))->height());
78 scrollbar_.set_steps(1);
79 scrollbar_.set_force_draw(scrollmode_ == ScrollMode::kScrollNormalForced ||
80 scrollmode_ == ScrollMode::kScrollLogForced);
81
82- recompute();
83+ layout();
84 }
85
86
87@@ -88,12 +86,16 @@
88 // We wrap the text twice. We need to do this to account for the presence/absence of the scollbar.
89 bool scrollbar_was_enabled = scrollbar_.is_enabled();
90 for (int i = 0; i < 2; ++i) {
91- if (text_.compare(0, 3, "<rt")) {
92- isrichtext = false;
93+ if (!is_richtext(text_)) {
94+ use_old_renderer_ = false;
95 const Image* text_im = UI::g_fh1->render(make_richtext(), get_eff_w() - 2 * RICHTEXT_MARGIN);
96 height = text_im->height();
97+ } else if (force_new_renderer_) {
98+ use_old_renderer_ = false;
99+ const Image* text_im = UI::g_fh1->render(text_, get_eff_w() - 2 * RICHTEXT_MARGIN);
100+ height = text_im->height();
101 } else {
102- isrichtext = true;
103+ use_old_renderer_ = true;
104 rt.set_width(get_eff_w() - 2 * RICHTEXT_MARGIN);
105 rt.parse(text_);
106 height = rt.height() + 2 * RICHTEXT_MARGIN;
107@@ -128,14 +130,15 @@
108 {
109 }
110
111-/// Take care about scrollbar on resize
112+/// Take care of the scrollbar on resize
113 void MultilineTextarea::layout()
114 {
115 recompute();
116
117- // Take care about the scrollbar
118+ // Take care of the scrollbar
119 scrollbar_.set_pos(Point(get_w() - Scrollbar::kSize, 0));
120 scrollbar_.set_size(Scrollbar::kSize, get_h());
121+ scrollbar_.set_pagesize(get_h() - 2 * UI_FONT_SIZE_BIG);
122 }
123
124 /**
125@@ -143,10 +146,15 @@
126 */
127 void MultilineTextarea::draw(RenderTarget& dst)
128 {
129- if (isrichtext) {
130+ if (use_old_renderer_) {
131 rt.draw(dst, Point(RICHTEXT_MARGIN, RICHTEXT_MARGIN - scrollbar_.get_scrollpos()));
132 } else {
133- const Image* text_im = UI::g_fh1->render(make_richtext(), get_eff_w() - 2 * RICHTEXT_MARGIN);
134+ const Image* text_im;
135+ if (!is_richtext(text_)) {
136+ text_im = UI::g_fh1->render(make_richtext(), get_eff_w() - 2 * RICHTEXT_MARGIN);
137+ } else {
138+ text_im = UI::g_fh1->render(text_, get_eff_w() - 2 * RICHTEXT_MARGIN);
139+ }
140
141 uint32_t blit_width = std::min(text_im->width(), static_cast<int>(get_eff_w()));
142 uint32_t blit_height = std::min(text_im->height(), static_cast<int>(get_inner_h()));
143
144=== modified file 'src/ui_basic/multilinetextarea.h'
145--- src/ui_basic/multilinetextarea.h 2016-04-01 12:22:09 +0000
146+++ src/ui_basic/multilinetextarea.h 2016-05-06 08:30:33 +0000
147@@ -58,6 +58,7 @@
148 uint32_t get_eff_w() const {return scrollbar_.is_enabled() ? get_w() - Scrollbar::kSize : get_w();}
149
150 void set_color(RGBColor fg) {color_ = fg;}
151+ void force_new_renderer() {force_new_renderer_ = true;}
152
153 // Drawing and event handlers
154 void draw(RenderTarget&) override;
155@@ -82,7 +83,8 @@
156 RGBColor color_;
157 Align align_;
158
159- bool isrichtext;
160+ bool force_new_renderer_;
161+ bool use_old_renderer_;
162 RichText rt;
163
164 Scrollbar scrollbar_;
165
166=== modified file 'src/ui_basic/scrollbar.cc'
167--- src/ui_basic/scrollbar.cc 2016-03-25 17:01:05 +0000
168+++ src/ui_basic/scrollbar.cc 2016-05-06 08:30:33 +0000
169@@ -85,6 +85,7 @@
170 set_scrollpos(steps - 1);
171
172 steps_ = steps;
173+ layout();
174 }
175
176
177@@ -111,6 +112,7 @@
178 singlestepsize = 1;
179
180 singlestepsize_ = singlestepsize;
181+ layout();
182 }
183
184
185@@ -120,6 +122,7 @@
186 void Scrollbar::set_pagesize(int32_t const pagesize)
187 {
188 pagesize_ = pagesize < 1 ? 1 : pagesize;
189+ layout();
190 }
191
192
193
194=== modified file 'src/ui_fsmenu/launch_mpg.cc'
195--- src/ui_fsmenu/launch_mpg.cc 2016-04-05 07:51:48 +0000
196+++ src/ui_fsmenu/launch_mpg.cc 2016-05-06 08:30:33 +0000
197@@ -234,7 +234,7 @@
198 // Y coordinate will be set later, when we know how high this box will get.
199 suggested_teams_box_ = new UI::SuggestedTeamsBox
200 (this, right_column_x_, 0, UI::Box::Vertical,
201- padding_, indent_, label_height_,
202+ padding_, indent_,
203 get_w() - right_column_x_, 4 * label_height_);
204 }
205
206
207=== modified file 'src/ui_fsmenu/mapselect.cc'
208--- src/ui_fsmenu/mapselect.cc 2016-03-25 17:40:51 +0000
209+++ src/ui_fsmenu/mapselect.cc 2016-05-06 08:30:33 +0000
210@@ -31,6 +31,7 @@
211 #include "logic/game_controller.h"
212 #include "logic/game_settings.h"
213 #include "map_io/widelands_map_loader.h"
214+#include "wui/map_tags.h"
215
216 // TODO(GunChleoc): Arabic: line height broken for descriptions for Arabic.
217 // Fix align for table headings & entries and for wordwrap.
218@@ -52,7 +53,7 @@
219 table_(this, tablex_, tabley_, tablew_, tableh_, false),
220 map_details_(this, right_column_x_, tabley_,
221 get_right_column_w(right_column_x_),
222- tableh_ - buth_ - 4 * padding_),
223+ tableh_ - buth_ - 4 * padding_, MapDetails::Style::kFsMenu),
224
225 basedir_("maps"),
226 settings_(settings),
227@@ -94,27 +95,27 @@
228 vbox = new UI::Box(this,
229 tablex_, vbox->get_y() + vbox->get_h() + padding_,
230 UI::Box::Horizontal, checkbox_space_, get_w());
231- add_tag_checkbox(vbox, "official", _("Official"));
232- add_tag_checkbox(vbox, "unbalanced", _("Unbalanced"));
233- add_tag_checkbox(vbox, "seafaring", _("Seafaring"));
234- add_tag_checkbox(vbox, "artifacts", _("Artifacts"));
235- add_tag_checkbox(vbox, "scenario", _("Scenario"));
236- vbox->set_size(get_w() - 2 * tablex_, checkbox_space_);
237-
238- vbox = new UI::Box(this,
239- tablex_, vbox->get_y() + vbox->get_h() + padding_,
240- UI::Box::Horizontal, checkbox_space_, get_w());
241- add_tag_checkbox(vbox, "ffa", _("Free for all"));
242- add_tag_checkbox(vbox, "1v1", _("1v1"));
243-
244- vbox->set_size(get_w() - 2 * tablex_, checkbox_space_);
245-
246- vbox = new UI::Box(this,
247- tablex_, vbox->get_y() + vbox->get_h() + padding_,
248- UI::Box::Horizontal, checkbox_space_, get_w());
249- add_tag_checkbox(vbox, "2teams", _("Teams of 2"));
250- add_tag_checkbox(vbox, "3teams", _("Teams of 3"));
251- add_tag_checkbox(vbox, "4teams", _("Teams of 4"));
252+ add_tag_checkbox(vbox, "official", localize_tag("official"));
253+ add_tag_checkbox(vbox, "unbalanced", localize_tag("unbalanced"));
254+ add_tag_checkbox(vbox, "seafaring", localize_tag("seafaring"));
255+ add_tag_checkbox(vbox, "artifacts", localize_tag("artifacts"));
256+ add_tag_checkbox(vbox, "scenario", localize_tag("scenario"));
257+ vbox->set_size(get_w() - 2 * tablex_, checkbox_space_);
258+
259+ vbox = new UI::Box(this,
260+ tablex_, vbox->get_y() + vbox->get_h() + padding_,
261+ UI::Box::Horizontal, checkbox_space_, get_w());
262+ add_tag_checkbox(vbox, "ffa", localize_tag("ffa"));
263+ add_tag_checkbox(vbox, "1v1", localize_tag("1v1"));
264+
265+ vbox->set_size(get_w() - 2 * tablex_, checkbox_space_);
266+
267+ vbox = new UI::Box(this,
268+ tablex_, vbox->get_y() + vbox->get_h() + padding_,
269+ UI::Box::Horizontal, checkbox_space_, get_w());
270+ add_tag_checkbox(vbox, "2teams", localize_tag("2teams"));
271+ add_tag_checkbox(vbox, "3teams", localize_tag("3teams"));
272+ add_tag_checkbox(vbox, "4teams", localize_tag("4teams"));
273 vbox->set_size(get_w() - 2 * tablex_, checkbox_space_);
274
275 scenario_types_ = settings_->settings().multiplayer ? Map::MP_SCENARIO : Map::SP_SCENARIO;
276
277=== modified file 'src/wui/CMakeLists.txt'
278--- src/wui/CMakeLists.txt 2016-04-02 16:45:53 +0000
279+++ src/wui/CMakeLists.txt 2016-05-06 08:30:33 +0000
280@@ -63,6 +63,8 @@
281 mapdata.h
282 maptable.cc
283 maptable.h
284+ map_tags.cc
285+ map_tags.h
286 suggested_teams_box.cc
287 suggested_teams_box.h
288 DEPENDS
289
290=== added file 'src/wui/map_tags.cc'
291--- src/wui/map_tags.cc 1970-01-01 00:00:00 +0000
292+++ src/wui/map_tags.cc 2016-05-06 08:30:33 +0000
293@@ -0,0 +1,60 @@
294+/*
295+ * Copyright (C) 2016 by the Widelands Development Team
296+ *
297+ * This program is free software; you can redistribute it and/or
298+ * modify it under the terms of the GNU General Public License
299+ * as published by the Free Software Foundation; either version 2
300+ * of the License, or (at your option) any later version.
301+ *
302+ * This program is distributed in the hope that it will be useful,
303+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
304+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
305+ * GNU General Public License for more details.
306+ *
307+ * You should have received a copy of the GNU General Public License
308+ * along with this program; if not, write to the Free Software
309+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
310+ *
311+ */
312+
313+#include "wui/map_tags.h"
314+
315+#include "base/i18n.h"
316+
317+namespace {
318+
319+const std::map<std::string, std::string> kMapTags = {
320+ /** TRANSLATORS: This is a map tag */
321+ {"official", _("Official")},
322+ /** TRANSLATORS: This is a map tag */
323+ {"unbalanced", _("Unbalanced")},
324+ /** TRANSLATORS: This is a map tag */
325+ {"seafaring", _("Seafaring")},
326+ /** TRANSLATORS: This is a map tag */
327+ {"artifacts", _("Artifacts")},
328+ /** TRANSLATORS: This is a map tag */
329+ {"scenario", _("Scenario")},
330+ /** TRANSLATORS: This is a map tag */
331+ {"ffa", _("Free for all")},
332+ /** TRANSLATORS: This is a map tag. One versus one. */
333+ {"1v1", _("1v1")},
334+ /** TRANSLATORS: This is a map tag */
335+ {"2teams", _("Teams of 2")},
336+ /** TRANSLATORS: This is a map tag */
337+ {"3teams", _("Teams of 3")},
338+ /** TRANSLATORS: This is a map tag */
339+ {"4teams", _("Teams of 4")},
340+};
341+
342+} // namespace
343+
344+bool tag_exists(const std::string& tag) {
345+ return kMapTags.count(tag) == 1;
346+}
347+
348+const std::string localize_tag(const std::string& tag) {
349+ if (tag_exists(tag)) {
350+ return _((*kMapTags.find(tag)).second);
351+ }
352+ return tag;
353+}
354
355=== added file 'src/wui/map_tags.h'
356--- src/wui/map_tags.h 1970-01-01 00:00:00 +0000
357+++ src/wui/map_tags.h 2016-05-06 08:30:33 +0000
358@@ -0,0 +1,35 @@
359+/*
360+ * Copyright (C) 2016 by the Widelands Development Team
361+ *
362+ * This program is free software; you can redistribute it and/or
363+ * modify it under the terms of the GNU General Public License
364+ * as published by the Free Software Foundation; either version 2
365+ * of the License, or (at your option) any later version.
366+ *
367+ * This program is distributed in the hope that it will be useful,
368+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
369+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
370+ * GNU General Public License for more details.
371+ *
372+ * You should have received a copy of the GNU General Public License
373+ * along with this program; if not, write to the Free Software
374+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
375+ *
376+ */
377+
378+#ifndef WL_WUI_MAP_TAGS_H
379+#define WL_WUI_MAP_TAGS_H
380+
381+#include <map>
382+#include <string>
383+
384+/// Functions for localizing the known map tags.
385+
386+/// Returns true if this tag is known.
387+bool tag_exists(const std::string& tag);
388+
389+/// If tag_exists, returns the localized tag.
390+/// Otherwise, returns 'tag'
391+const std::string localize_tag(const std::string& tag);
392+
393+#endif // end of include guard: WL_WUI_MAP_TAGS_H
394
395=== modified file 'src/wui/mapdata.cc'
396--- src/wui/mapdata.cc 2016-04-03 13:00:14 +0000
397+++ src/wui/mapdata.cc 2016-05-06 08:30:33 +0000
398@@ -30,10 +30,11 @@
399 MapData() {
400 i18n::Textdomain td("maps");
401 filename = init_filename;
402- name = map.get_name();
403- localized_name = name.empty() ? "" : _(name);
404+ name = map.get_name().empty() ? _("No Name") : map.get_name();
405+ localized_name = _(name);
406 // Localizing this, because some author fields now have "edited by" text.
407- authors = MapAuthorData(_(map.get_author()));
408+ const std::string& author = map.get_author();
409+ authors = MapAuthorData(author.empty() ? _("No Author") : _(author));
410 description = map.get_description().empty() ? "" : _(map.get_description());
411 hint = map.get_hint().empty() ? "" : _(map.get_hint());
412 nrplayers = map.get_nrplayers();
413
414=== modified file 'src/wui/mapdetails.cc'
415--- src/wui/mapdetails.cc 2016-04-01 18:05:40 +0000
416+++ src/wui/mapdetails.cc 2016-05-06 08:30:33 +0000
417@@ -1,5 +1,5 @@
418 /*
419- * Copyright (C) 2002, 2006-2015 by the Widelands Development Team
420+ * Copyright (C) 2002-2016 by the Widelands Development Team
421 *
422 * This program is free software; you can redistribute it and/or
423 * modify it under the terms of the GNU General Public License
424@@ -18,6 +18,7 @@
425
426 #include "wui/mapdetails.h"
427
428+#include <algorithm>
429 #include <cstdio>
430 #include <memory>
431
432@@ -33,74 +34,72 @@
433 #include "logic/game_settings.h"
434 #include "map_io/widelands_map_loader.h"
435 #include "ui_basic/box.h"
436+#include "wui/map_tags.h"
437+
438+namespace {
439+std::string as_header(const std::string& txt, MapDetails::Style style, bool is_first = false) {
440+ switch (style) {
441+ case MapDetails::Style::kFsMenu:
442+ return (boost::format("<p><font size=%i bold=1 shadow=1>%s%s</font></p>")
443+ % UI_FONT_SIZE_SMALL
444+ % (is_first ? "" : "<vspace gap=9>")
445+ % richtext_escape(txt)).str();
446+ case MapDetails::Style::kWui:
447+ return (boost::format("<p><font size=%i bold=1 color=D1D1D1>%s%s</font></p>")
448+ % UI_FONT_SIZE_SMALL
449+ % (is_first ? "" : "<vspace gap=6>")
450+ % richtext_escape(txt)).str();
451+ default:
452+ NEVER_HERE();
453+ }
454+}
455+std::string as_content(const std::string& txt, MapDetails::Style style) {
456+ switch (style) {
457+ case MapDetails::Style::kFsMenu:
458+ return (boost::format("<p><font size=%i bold=1 color=D1D1D1 shadow=1><vspace gap=2>%s</font></p>")
459+ % UI_FONT_SIZE_SMALL
460+ % richtext_escape(txt)).str();
461+ case MapDetails::Style::kWui:
462+ return (boost::format("<p><font size=%i><vspace gap=2>%s</font></p>")
463+ % (UI_FONT_SIZE_SMALL - 2)
464+ % richtext_escape(txt)).str();
465+ default:
466+ NEVER_HERE();
467+ }
468+}
469+} // namespace
470
471 MapDetails::MapDetails
472- (Panel* parent, int32_t x, int32_t y, int32_t max_x, int32_t max_y) :
473- UI::Panel(parent, x, y, max_x, max_y),
474+ (Panel* parent, int32_t x, int32_t y, int32_t max_w, int32_t max_h, Style style) :
475+ UI::Panel(parent, x, y, max_w, max_h),
476
477+ style_(style),
478 padding_(4),
479- indent_(10),
480- labelh_(20),
481- max_w_(max_x),
482- max_h_(max_y),
483- // Subtract for main box and author box
484- descr_box_height_(max_y - 4 * labelh_ - 5 * padding_),
485-
486- main_box_(this, 0, 0, UI::Box::Vertical,
487- max_w_, max_h_, 0),
488-
489- name_box_(&main_box_, 0, 0, UI::Box::Horizontal,
490- max_w_, 3 * labelh_ + padding_, padding_ / 2),
491- name_label_(&main_box_, 0, 0, max_w_ - padding_, labelh_, ""),
492- name_(&name_box_, 0, 0, max_w_ - indent_, 2 * labelh_, ""),
493-
494- author_box_(&main_box_, 0, 0, UI::Box::Horizontal,
495- max_w_, 3 * labelh_ + padding_, padding_ / 2),
496- author_label_(&main_box_, 0, 0, max_w_ - padding_, labelh_, ""),
497- author_(&author_box_, 0, 0, max_w_ - indent_, labelh_, ""),
498-
499- descr_box_(&main_box_, 0, 0, UI::Box::Horizontal,
500- max_w_, descr_box_height_, padding_ / 2),
501- descr_label_(&main_box_, 0, 0, max_w_, labelh_, ""),
502- // -1 to prevent cropping of scrollbar
503- descr_(&descr_box_, 0, 0, max_w_ - indent_ - 1, descr_box_height_ - labelh_ - padding_, "")
504+ main_box_(this, 0, 0, UI::Box::Vertical, max_w, max_h, 0),
505+ name_label_(&main_box_, 0, 0, max_w - padding_, 20, "", UI::Align::kLeft,
506+ UI::MultilineTextarea::ScrollMode::kNoScrolling),
507+ descr_(&main_box_, 0, 0, max_w, 20, ""),
508+ suggested_teams_box_(new UI::SuggestedTeamsBox(this, 0, 0, UI::Box::Vertical, padding_, 0, max_w))
509 {
510- suggested_teams_box_ = new UI::SuggestedTeamsBox(this, 0, 0, UI::Box::Vertical,
511- padding_, indent_, labelh_, max_w_, 4 * labelh_);
512+ name_label_.force_new_renderer();
513+ descr_.force_new_renderer();
514
515 main_box_.add(&name_label_, UI::Align::kLeft);
516- name_box_.add_space(indent_);
517- name_box_.add(&name_, UI::Align::kLeft);
518- main_box_.add(&name_box_, UI::Align::kLeft);
519- main_box_.add_space(padding_);
520-
521- main_box_.add(&author_label_, UI::Align::kLeft);
522- author_box_.add_space(indent_);
523- author_box_.add(&author_, UI::Align::kLeft);
524- main_box_.add(&author_box_, UI::Align::kLeft);
525- main_box_.add_space(padding_);
526-
527- main_box_.add(&descr_label_, UI::Align::kLeft);
528- descr_box_.add_space(indent_);
529- descr_box_.add(&descr_, UI::Align::kLeft);
530- main_box_.add(&descr_box_, UI::Align::kLeft);
531- main_box_.add_space(padding_);
532+ main_box_.add_space(padding_);
533+ main_box_.add(&descr_, UI::Align::kLeft);
534+ main_box_.set_size(max_w, max_h); // We need to initialize the width, set_max_height will set the height
535+ set_max_height(max_h);
536 }
537
538
539 void MapDetails::clear() {
540 name_label_.set_text("");
541- author_label_.set_text("");
542- descr_label_.set_text("");
543- name_.set_text("");
544- author_.set_text("");
545 descr_.set_text("");
546 suggested_teams_box_->hide();
547 }
548
549 void MapDetails::set_max_height(int new_height) {
550 max_h_ = new_height;
551- descr_box_height_ = max_h_ - 4 * labelh_ - 5 * padding_;
552 update_layout();
553 }
554
555@@ -108,58 +107,75 @@
556 // Adjust sizes for show / hide suggested teams
557 if (suggested_teams_box_->is_visible()) {
558 suggested_teams_box_->set_pos(Point(0, max_h_ - suggested_teams_box_->get_h()));
559- main_box_.set_size(max_w_, max_h_ - suggested_teams_box_->get_h());
560- descr_box_.set_size(
561- descr_box_.get_w(),
562- descr_box_height_ - suggested_teams_box_->get_h() - padding_);
563+ main_box_.set_size(main_box_.get_w(), max_h_ - suggested_teams_box_->get_h() - padding_);
564 } else {
565- main_box_.set_size(max_w_, max_h_);
566- descr_box_.set_size(descr_box_.get_w(), descr_box_height_);
567+ main_box_.set_size(main_box_.get_w(), max_h_);
568 }
569- descr_.set_size(descr_.get_w(), descr_box_.get_h() - descr_label_.get_h() - padding_);
570+ descr_.set_size(descr_.get_w(), main_box_.get_h() - name_label_.get_h() - padding_);
571 descr_.scroll_to_top();
572 }
573
574 void MapDetails::update(const MapData& mapdata, bool localize_mapname) {
575 clear();
576+ // Show directory information
577 if (mapdata.maptype == MapData::MapType::kDirectory) {
578- // Show directory information
579- name_label_.set_text(_("Directory:"));
580- name_.set_text(mapdata.localized_name);
581- name_.set_tooltip(_("The name of this directory"));
582- main_box_.set_size(max_w_, max_h_);
583- } else {
584- // Show map information
585- if (mapdata.maptype == MapData::MapType::kScenario) {
586- name_label_.set_text(_("Scenario:"));
587- } else {
588- name_label_.set_text(_("Map:"));
589- }
590- name_.set_text(localize_mapname ? mapdata.localized_name : mapdata.name);
591+ name_label_.set_text((boost::format("<rt>%s%s</rt>")
592+ % as_header(_("Directory:"), style_, true)
593+ % as_content(mapdata.localized_name, style_)).str());
594+ main_box_.set_size(main_box_.get_w(), max_h_);
595+
596+ } else { // Show map information
597+ name_label_.set_text(
598+ (boost::format("<rt>%s%s</rt>")
599+ % as_header(mapdata.maptype == MapData::MapType::kScenario ?
600+ _("Scenario:") : _("Map:"), style_, true)
601+ % as_content(localize_mapname ? mapdata.localized_name : mapdata.name, style_)).str());
602+
603 if (mapdata.localized_name != mapdata.name) {
604 if (localize_mapname) {
605- name_.set_tooltip
606+ name_label_.set_tooltip
607 /** TRANSLATORS: Tooltip in map description when translated map names are being displayed. */
608 /** TRANSLATORS: %s is the English name of the map. */
609 ((boost::format(_("The original name of this map: %s"))
610 % mapdata.name).str());
611 } else {
612- name_.set_tooltip
613+ name_label_.set_tooltip
614 /** TRANSLATORS: Tooltip in map description when map names are being displayed in English. */
615 /** TRANSLATORS: %s is the localized name of the map. */
616 ((boost::format(_("The name of this map in your language: %s"))
617 % mapdata.localized_name).str());
618 }
619- } else {
620- name_.set_tooltip(_("The name of this map"));
621- }
622- author_label_.set_text(ngettext("Author:", "Authors:", mapdata.authors.get_number()));
623- author_.set_text(mapdata.authors.get_names());
624- descr_label_.set_text(_("Description:"));
625- descr_.set_text(
626- mapdata.description +
627- /** TRANSLATORS: Map hint header when selecting a map. */
628- (mapdata.hint.empty() ? "" : (std::string("\n\n") + _("HINT:") + "\n" + mapdata.hint)));
629+ }
630+
631+ // Show map information
632+ std::string description =
633+ as_header(ngettext("Author:", "Authors:", mapdata.authors.get_number()), style_);
634+ description = (boost::format("%s%s")
635+ % description
636+ % as_content(mapdata.authors.get_names(), style_)).str();
637+
638+ std::vector<std::string> tags;
639+ for (const auto& tag : mapdata.tags) {
640+ tags.push_back(localize_tag(tag));
641+ }
642+ std::sort(tags.begin(), tags.end());
643+ description = (boost::format("%s%s") % description % as_header(_("Tags:"), style_)).str();
644+ description = (boost::format("%s%s")
645+ % description %
646+ as_content(i18n::localize_list(tags, i18n::ConcatenateWith::COMMA), style_))
647+ .str();
648+
649+ description = (boost::format("%s%s") % description % as_header(_("Description:"), style_)).str();
650+ description = (boost::format("%s%s") % description % as_content(mapdata.description, style_)).str();
651+
652+ if (!mapdata.hint.empty()) {
653+ /** TRANSLATORS: Map hint header when selecting a map. */
654+ description = (boost::format("%s%s") % description % as_header(_("Hint:"), style_)).str();
655+ description = (boost::format("%s%s") % description % as_content(mapdata.hint, style_)).str();
656+ }
657+
658+ description = (boost::format("<rt>%s</rt>") % description).str();
659+ descr_.set_text(description);
660
661 // Show / hide suggested teams
662 if (mapdata.suggested_teams.empty()) {
663
664=== modified file 'src/wui/mapdetails.h'
665--- src/wui/mapdetails.h 2016-03-23 08:47:27 +0000
666+++ src/wui/mapdetails.h 2016-05-06 08:30:33 +0000
667@@ -23,7 +23,6 @@
668 #include "ui_basic/box.h"
669 #include "ui_basic/multilinetextarea.h"
670 #include "ui_basic/panel.h"
671-#include "ui_basic/textarea.h"
672 #include "wui/mapdata.h"
673 #include "wui/suggested_teams_box.h"
674
675@@ -33,9 +32,12 @@
676 */
677 class MapDetails : public UI::Panel {
678 public:
679- MapDetails(Panel * parent,
680- int32_t x, int32_t y,
681- int32_t max_x, int32_t max_y);
682+ enum class Style {
683+ kFsMenu,
684+ kWui
685+ };
686+
687+ MapDetails(Panel* parent, int32_t x, int32_t y, int32_t max_w, int32_t max_h, Style style);
688
689 void clear();
690 void set_max_height(int new_height);
691@@ -43,23 +45,13 @@
692 void update(const MapData& mapdata, bool localize_mapname);
693
694 private:
695- const int padding_, indent_, labelh_, max_w_;
696- int max_h_, descr_box_height_;
697+ const Style style_;
698+ const int padding_;
699+ int max_h_;
700
701 UI::Box main_box_;
702-
703- UI::Box name_box_;
704- UI::Textarea name_label_;
705- UI::MultilineTextarea name_;
706-
707- UI::Box author_box_;
708- UI::Textarea author_label_;
709- UI::MultilineTextarea author_;
710-
711- UI::Box descr_box_;
712- UI::Textarea descr_label_;
713+ UI::MultilineTextarea name_label_;
714 UI::MultilineTextarea descr_;
715-
716 UI::SuggestedTeamsBox* suggested_teams_box_;
717 };
718
719
720=== modified file 'src/wui/suggested_teams_box.cc'
721--- src/wui/suggested_teams_box.cc 2016-02-10 20:39:02 +0000
722+++ src/wui/suggested_teams_box.cc 2016-05-06 08:30:33 +0000
723@@ -42,13 +42,12 @@
724 SuggestedTeamsBox::SuggestedTeamsBox(Panel * parent,
725 int32_t x, int32_t y,
726 uint32_t orientation,
727- int32_t padding, int32_t indent, int32_t label_height,
728- int32_t max_x, int32_t max_y,
729- uint32_t inner_spacing) :
730- UI::Box(parent, x, y, orientation, max_x, max_y, inner_spacing),
731+ int32_t padding, int32_t indent,
732+ int32_t max_x, int32_t max_y) :
733+ UI::Box(parent, x, y, orientation, max_x, max_y, g_gr->images().get(player_pictures_small[0])->height()),
734 padding_(padding),
735 indent_(indent),
736- label_height_(label_height)
737+ label_height_(g_gr->images().get(player_pictures_small[0])->height() + padding)
738 {
739 player_icons_.clear();
740 suggested_teams_.clear();
741@@ -105,10 +104,10 @@
742 for (const Widelands::Map::SuggestedTeamLineup& lineup : suggested_teams_) {
743
744 lineup_box_ =
745- new UI::Box(this, indent_, teamlist_offset + lineup_counter * (label_height_ + padding_),
746+ new UI::Box(this, indent_, teamlist_offset + lineup_counter * (label_height_),
747 UI::Box::Horizontal, get_w() - indent_);
748
749- lineup_box_->set_size(get_w(), label_height_ + padding_);
750+ lineup_box_->set_size(get_w(), label_height_);
751
752 bool is_first = true;
753 for (const Widelands::Map::SuggestedTeam& team : lineup) {
754@@ -127,7 +126,8 @@
755 assert(player < MAX_PLAYERS);
756 const Image* player_image = g_gr->images().get(player_pictures_small[player]);
757 assert(player_image);
758- player_icon = new UI::Icon(lineup_box_, 0, 0, 20, 20, player_image);
759+ player_icon = new UI::Icon(lineup_box_, 0, 0,
760+ player_image->width(), player_image->height(), player_image);
761 player_icon->set_visible(true);
762 player_icon->set_no_frame();
763 lineup_box_->add(player_icon, UI::Align::kLeft);
764@@ -138,7 +138,7 @@
765 } // All lineups
766
767 // Adjust size to content
768- set_size(get_w(), teamlist_offset + lineup_counter * (label_height_ + padding_));
769+ set_size(get_w(), teamlist_offset + lineup_counter * (label_height_));
770 }
771 }
772
773
774=== modified file 'src/wui/suggested_teams_box.h'
775--- src/wui/suggested_teams_box.h 2016-01-24 20:11:53 +0000
776+++ src/wui/suggested_teams_box.h 2016-05-06 08:30:33 +0000
777@@ -36,9 +36,8 @@
778 SuggestedTeamsBox(Panel * parent,
779 int32_t x, int32_t y,
780 uint32_t orientation,
781- int32_t padding, int32_t indent, int32_t label_height,
782- int32_t max_x = 0, int32_t max_y = 0,
783- uint32_t inner_spacing = 0);
784+ int32_t padding, int32_t indent,
785+ int32_t max_x = 0, int32_t max_y = 0);
786 ~SuggestedTeamsBox();
787
788 void hide();

Subscribers

People subscribed via source and target branches

to status/vote changes: