← Back to team overview

widelands-dev team mailing list archive

[Merge] lp:~nomeata/widelands/plot-improvements into lp:widelands

 

Joachim Breitner has proposed merging lp:~nomeata/widelands/plot-improvements into lp:widelands.

Requested reviews:
  Widelands Developers (widelands-dev)
Related bugs:
  Bug #536543 in widelands: "Add "whole game" to the time axis in statistics"
  https://bugs.launchpad.net/widelands/+bug/536543
  Bug #672085 in widelands: "New stock menu layout too high for small resolutions"
  https://bugs.launchpad.net/widelands/+bug/672085
  Bug #886709 in widelands: "new slider statistics menu opens in wrong position or so"
  https://bugs.launchpad.net/widelands/+bug/886709

For more details, see:
https://code.launchpad.net/~nomeata/widelands/plot-improvements/+merge/81399

This should be the fix for #886709. Good morning by the way.

Additionally, it uses UI::Box'es for the layout, and improves some of the code in Boxes and Sliders.
-- 
https://code.launchpad.net/~nomeata/widelands/plot-improvements/+merge/81399
Your team Widelands Developers is requested to review the proposed merge of lp:~nomeata/widelands/plot-improvements into lp:widelands.
=== modified file 'src/ui_basic/box.cc'
--- src/ui_basic/box.cc	2011-02-24 18:56:13 +0000
+++ src/ui_basic/box.cc	2011-11-06 12:40:30 +0000
@@ -34,7 +34,7 @@
 	(Panel * const parent,
 	 int32_t const x, int32_t const y,
 	 uint32_t const orientation,
-	 int32_t const max_x, int32_t const max_y)
+	 int32_t const max_x, int32_t const max_y, uint32_t const inner_spacing)
 	:
 	Panel        (parent, x, y, 0, 0),
 
@@ -44,7 +44,8 @@
 	m_scrolling(false),
 	m_scrollbar(0),
 	m_orientation(orientation),
-	m_mindesiredbreadth(0)
+	m_mindesiredbreadth(0),
+	m_inner_spacing(inner_spacing)
 {}
 
 /**
@@ -96,6 +97,9 @@
 			maxbreadth = breadth;
 	}
 
+	if (m_items.size())
+		totaldepth += (m_items.size() - 1) * m_inner_spacing;
+
 	if (m_orientation == Horizontal) {
 		if (totaldepth > m_max_x && m_scrolling) {
 			maxbreadth += Scrollbar::Size;
@@ -107,7 +111,8 @@
 			maxbreadth += Scrollbar::Size;
 		}
 		set_desired_size
-			(std::min(maxbreadth, m_max_x), std::min(totaldepth, m_max_y));
+			(std::min(maxbreadth, m_max_x) + get_lborder() + get_rborder(),
+			 std::min(totaldepth, m_max_y) + get_tborder() + get_bborder());
 	}
 
 	//  This is not redundant, because even if all this does not change our
@@ -121,7 +126,7 @@
  */
 void Box::layout()
 {
-	uint32_t totalbreadth = m_orientation == Horizontal ? get_w() : get_h();
+	uint32_t totalbreadth = m_orientation == Horizontal ? get_inner_w() : get_inner_h();
 
 	// First pass: compute the depth and adjust whether we have a scrollbar
 	uint32_t totaldepth = 0;
@@ -133,6 +138,9 @@
 		totaldepth += depth;
 	}
 
+	if (m_items.size())
+		totaldepth += (m_items.size() - 1) * m_inner_spacing;
+
 	bool needscrollbar = false;
 	if (m_orientation == Horizontal) {
 		if (totaldepth > m_max_x && m_scrolling) {
@@ -151,16 +159,16 @@
 		int32_t pagesize;
 		if (m_orientation == Horizontal) {
 			sb_x = 0;
-			sb_y = get_h() - Scrollbar::Size;
-			sb_w = get_w();
+			sb_y = get_inner_h() - Scrollbar::Size;
+			sb_w = get_inner_w();
 			sb_h = Scrollbar::Size;
-			pagesize = get_w() - Scrollbar::Size;
+			pagesize = get_inner_w() - Scrollbar::Size;
 		} else {
-			sb_x = get_w() - Scrollbar::Size;
+			sb_x = get_inner_w() - Scrollbar::Size;
 			sb_y = 0;
 			sb_w = Scrollbar::Size;
-			sb_h = get_h();
-			pagesize = get_h() - Scrollbar::Size;
+			sb_h = get_inner_h();
+			pagesize = get_inner_h() - Scrollbar::Size;
 		}
 		if (!m_scrollbar) {
 			m_scrollbar = new Scrollbar
@@ -189,7 +197,7 @@
 	int32_t scrollpos = m_scrollbar ? m_scrollbar->get_scrollpos() : 0;
 
 	uint32_t totaldepth = 0;
-	uint32_t totalbreadth = m_orientation == Horizontal ? get_h() : get_w();
+	uint32_t totalbreadth = m_orientation == Horizontal ? get_inner_h() : get_inner_w();
 	if (m_scrollbar)
 		totalbreadth -= Scrollbar::Size;
 
@@ -205,6 +213,7 @@
 		}
 
 		totaldepth += depth;
+		totaldepth += m_inner_spacing;
 	}
 }
 
@@ -315,11 +324,11 @@
 		int32_t breadth, maxbreadth;
 
 		if (m_orientation == Horizontal) {
-			breadth = it.u.panel.panel->get_h();
-			maxbreadth = get_h();
+			breadth = it.u.panel.panel->get_inner_h();
+			maxbreadth = get_inner_h();
 		} else {
-			breadth = it.u.panel.panel->get_w();
-			maxbreadth = get_w();
+			breadth = it.u.panel.panel->get_inner_w();
+			maxbreadth = get_inner_w();
 		}
 		switch (it.u.panel.align) {
 		case AlignLeft:

=== modified file 'src/ui_basic/box.h'
--- src/ui_basic/box.h	2011-02-24 18:56:13 +0000
+++ src/ui_basic/box.h	2011-11-06 12:40:30 +0000
@@ -48,7 +48,8 @@
 		(Panel * parent,
 		 int32_t x, int32_t y,
 		 uint32_t orientation,
-		 int32_t max_x = 0, int32_t max_y = 0);
+		 int32_t max_x = 0, int32_t max_y = 0,
+		 uint32_t inner_spacing = 0);
 
 	void set_scrolling(bool scroll);
 
@@ -97,6 +98,7 @@
 	Scrollbar * m_scrollbar;
 	uint32_t m_orientation;
 	uint32_t m_mindesiredbreadth;
+	uint32_t m_inner_spacing;
 
 	std::vector<Item> m_items;
 };

=== modified file 'src/ui_basic/checkbox.cc'
--- src/ui_basic/checkbox.cc	2010-11-26 20:40:38 +0000
+++ src/ui_basic/checkbox.cc	2011-11-06 12:40:30 +0000
@@ -42,6 +42,7 @@
 	if (picid != g_gr->get_no_picture()) {
 		uint32_t w, h;
 		g_gr->get_picture_size(picid, w, h);
+		set_desired_size(w, h);
 		set_size(w, h);
 
 		set_flags(Has_Custom_Picture, true);

=== modified file 'src/ui_basic/radiobutton.cc'
--- src/ui_basic/radiobutton.cc	2011-11-04 17:40:44 +0000
+++ src/ui_basic/radiobutton.cc	2011-11-06 12:40:30 +0000
@@ -23,21 +23,6 @@
 
 namespace UI {
 
-struct Radiobutton : public Statebox {
-	friend struct Radiogroup;
-
-	Radiobutton
-		(Panel * parent, Point, PictureID picid, Radiogroup &, int32_t id);
-	~Radiobutton();
-
-private:
-	void clicked();
-
-	Radiobutton * m_nextbtn;
-	Radiogroup  & m_group;
-	int32_t           m_id;
-};
-
 /**
  * Initialize the radiobutton and link it into the group's linked list
 */
@@ -112,11 +97,13 @@
 	(Panel      * const parent,
 	 Point        const p,
 	 PictureID    const picid,
-	 char const * const tooltip)
+	 char const * const tooltip,
+	 Radiobutton **     ret_btn)
 {
 	++m_highestid;
-	(new Radiobutton(parent, p, picid, *this, m_highestid))->set_tooltip
-		(tooltip);
+	Radiobutton * btn = new Radiobutton(parent, p, picid, *this, m_highestid);
+	btn->set_tooltip(tooltip);
+	if (ret_btn) (*ret_btn) = btn;
 	return m_highestid;
 }
 

=== modified file 'src/ui_basic/radiobutton.h'
--- src/ui_basic/radiobutton.h	2011-11-04 17:40:44 +0000
+++ src/ui_basic/radiobutton.h	2011-11-06 12:40:30 +0000
@@ -24,18 +24,35 @@
 #include "point.h"
 #include "m_signal.h"
 
+#include "checkbox.h"
 
 #include <stdint.h>
 
 namespace UI {
+
 struct Panel;
 
+struct Radiogroup;
+
+struct Radiobutton : public Statebox {
+	friend struct Radiogroup;
+
+	Radiobutton
+		(Panel * parent, Point, PictureID picid, Radiogroup &, int32_t id);
+	~Radiobutton();
+
+private:
+	void clicked();
+
+	Radiobutton * m_nextbtn;
+	Radiogroup  & m_group;
+	int32_t           m_id;
+};
+
 /**
  * A group of radiobuttons. At most one of them is checked at any time.  State
  * is -1 if none is checked, otherwise it's the index of the checked button.
  */
-struct Radiobutton;
-
 struct Radiogroup {
 	friend struct Radiobutton;
 
@@ -47,12 +64,12 @@
 	Signal clicked; //  clicked without things changed
 
 	int32_t add_button
-		(Panel * parent, Point, PictureID picid, char const * tooltip = 0);
+		(Panel * parent, Point, PictureID picid, char const * tooltip = 0, Radiobutton ** = NULL);
 
 	int32_t get_state() const throw () {return m_state;}
 	void set_state(int32_t state);
 	void set_enabled(bool);
-
+	Radiobutton * get_button(int32_t id);
 private:
 	Radiobutton * m_buttons; //  linked list of buttons (not sorted)
 	int32_t           m_highestid;

=== modified file 'src/ui_basic/slider.cc'
--- src/ui_basic/slider.cc	2011-11-05 18:22:28 +0000
+++ src/ui_basic/slider.cc	2011-11-06 12:40:30 +0000
@@ -376,6 +376,12 @@
 	update();
 }
 
+void VerticalSlider::layout() {
+	m_x_gap = get_w() / 2 - 2;
+	m_bar_size = get_h() - m_cursor_size;
+	Slider::layout();
+}
+
 
 ////////////////////////////////////////////////////////////////////////////////
 //                               HORIZONTAL                                   //
@@ -457,6 +463,11 @@
 	} else return false;
 }
 
+void HorizontalSlider::layout() {
+	Slider::layout();
+	m_y_gap = get_h() / 2 - 2;
+	m_bar_size = get_w() - m_cursor_size;
+}
 
 ////////////////////////////////////////////////////////////////////////////////
 //                               VERTICAL                                     //
@@ -560,5 +571,14 @@
 
 }
 
+void DiscreteSlider::layout() {
+	uint32_t w = get_w();
+	uint32_t h = get_h();
+	slider.set_pos(Point(w / (2 * labels.size()) - slider.m_cursor_size / 2, 0));
+	slider.set_size
+		(w - (w / labels.size()) + slider.m_cursor_size,
+		 h - UI::Font::ui_small()->lineskip() - 2);
+	Panel::layout();
+}
 
 }

=== modified file 'src/ui_basic/slider.h'
--- src/ui_basic/slider.h	2011-11-04 21:42:45 +0000
+++ src/ui_basic/slider.h	2011-11-06 12:40:30 +0000
@@ -25,6 +25,8 @@
 
 namespace UI {
 
+struct DiscreteSlider;
+
 /**
  * \brief This class defines a generic slide bar.
  *
@@ -32,6 +34,8 @@
  */
 class Slider : public Panel {
 
+friend struct DiscreteSlider;
+
 protected:
 	Slider
 		(Panel * parent,
@@ -92,11 +96,11 @@
 
 	PictureID m_pic_background;    //  background texture (picture ID)
 
+protected:
 	int32_t m_x_gap;              //  draw positions
 	int32_t m_y_gap;
 	int32_t m_bar_size;
 
-protected:
 	int32_t m_cursor_pos;         //  cursor position
 	int32_t m_cursor_size;        //  cursor width
 };
@@ -132,6 +136,7 @@
 	void draw(RenderTarget & dst);
 	bool handle_mousemove (Uint8 btn, int32_t x, int32_t y, int32_t, int32_t);
 	bool handle_mousepress(Uint8 btn, int32_t x, int32_t y);
+	void layout();
 };
 
 
@@ -166,6 +171,7 @@
 	void draw(RenderTarget & dst);
 	bool handle_mousemove (Uint8 btn, int32_t x, int32_t y, int32_t, int32_t);
 	bool handle_mousepress(Uint8 btn, int32_t x, int32_t y);
+	void layout();
 };
 
 /**
@@ -208,6 +214,7 @@
 	const std::vector<std::string> labels;
 
 	void draw(RenderTarget & dst);
+	void layout();
 };
 
 

=== modified file 'src/wui/general_statistics_menu.cc'
--- src/wui/general_statistics_menu.cc	2011-11-05 21:32:08 +0000
+++ src/wui/general_statistics_menu.cc	2011-11-06 12:40:30 +0000
@@ -47,17 +47,17 @@
 UI::UniqueWindow
 	(&parent, "statistics_menu", &registry,
 	 440, 400, _("General Statistics")),
-m_plot          (this, 5, 5, 430, PLOT_HEIGHT)
+m_box           (this, 0, 0, UI::Box::Vertical, 0, 0, 5),
+m_plot          (&m_box, 0, 0, 430, PLOT_HEIGHT)
 {
+	set_center_panel(&m_box);
+	m_box.set_border(5, 5, 5, 5);
+
 	set_cache(false);
 
-	uint32_t const spacing =  5;
-	Point          pos       (spacing, spacing);
-
-	//  plotter
+	// Setup plot data
 	m_plot.set_sample_rate(STATISTICS_SAMPLE_TIME);
 	m_plot.set_plotmode(WUIPlot_Area::PLOTMODE_ABSOLUTE);
-	pos.y += PLOT_HEIGHT + spacing + spacing;
 
 	Game & game = *parent.get_game();
 	const Game::General_Stats_vector & genstats =
@@ -123,19 +123,22 @@
 			m_plot.show_plot(i * m_ndatasets, 1);
 	}
 
+	// Setup Widgets
+	m_box.add(&m_plot, UI::Box::AlignTop);
+
+	UI::Box * hbox1 = new UI::Box(&m_box, 0, 0, UI::Box::Horizontal, 0, 0, 1);
 
 	uint32_t plr_in_game = 0;
 	Player_Number const nr_players = game.map().get_nrplayers();
 	iterate_players_existing_const(p, nr_players, game, player) ++plr_in_game;
 
-	pos.x = spacing;
 	iterate_players_existing_const(p, nr_players, game, player) {
 		char buffer[36];
 		snprintf(buffer, sizeof(buffer), "pics/genstats_enable_plr_%02u.png", p);
 		UI::Callback_Button & cb =
 			*new UI::Callback_Button
-				(this, "playerbutton",
-				 pos.x, pos.y, 25, 25,
+				(hbox1, "playerbutton",
+				 0, 0, 25, 25,
 				 g_gr->get_picture(PicMod_UI, "pics/but4.png"),
 				 g_gr->get_picture(PicMod_Game, buffer),
 				 boost::bind
@@ -145,107 +148,129 @@
 				 player->get_name().c_str());
 		cb.set_perm_pressed(true);
 		m_cbs[p - 1] = &cb;
-		pos.x += 25 + spacing;
+
+		hbox1->add(&cb, UI::Box::AlignLeft);
 	} else //  player nr p does not exist
 		m_cbs[p - 1] = 0;
 
-	pos.x  = spacing;
-	pos.y += 25 + spacing + spacing;
-
-	int32_t button_size =
-		(get_inner_w() - spacing * (m_ndatasets + 1))
-		/
-		m_ndatasets;
+	m_box.add(hbox1, UI::Box::AlignTop);
+
+	UI::Box * hbox2 = new UI::Box(&m_box, 0, 0, UI::Box::Horizontal, 0, 0, 1);
+
+	UI::Radiobutton * btn;
+
 	m_radiogroup.add_button
-		(this,
-		 pos,
+		(hbox2,
+		 Point(0, 0),
 		 g_gr->get_picture(PicMod_Game, "pics/genstats_landsize.png"),
-		 _("Land"));
-	pos.x += button_size + spacing;
+		 _("Land"),
+		 &btn);
+	hbox2->add(btn, UI::Box::AlignLeft);
+
 	m_radiogroup.add_button
-		(this,
-		 pos,
+		(hbox2,
+		 Point(0, 0),
 		 g_gr->get_picture(PicMod_Game, "pics/genstats_nrworkers.png"),
-		 _("Workers"));
-	pos.x += button_size + spacing;
+		 _("Workers"),
+		 &btn);
+	hbox2->add(btn, UI::Box::AlignLeft);
+
 	m_radiogroup.add_button
-		(this,
-		 pos,
+		(hbox2,
+		 Point(0, 0),
 		 g_gr->get_picture(PicMod_Game, "pics/genstats_nrbuildings.png"),
-		 _("Buildings"));
-	pos.x += button_size + spacing;
+		 _("Buildings"),
+		 &btn);
+	hbox2->add(btn, UI::Box::AlignLeft);
+
 	m_radiogroup.add_button
-		(this,
-		 pos,
+		(hbox2,
+		 Point(0, 0),
 		 g_gr->get_picture(PicMod_Game, "pics/genstats_nrwares.png"),
-		 _("Wares"));
-	pos.x += button_size + spacing;
+		 _("Wares"),
+		 &btn);
+	hbox2->add(btn, UI::Box::AlignLeft);
+
 	m_radiogroup.add_button
-		(this,
-		 pos,
+		(hbox2,
+		 Point(0, 0),
 		 g_gr->get_picture(PicMod_Game, "pics/genstats_productivity.png"),
-		 _("Productivity"));
-	pos.x += button_size + spacing;
+		 _("Productivity"),
+		 &btn);
+	hbox2->add(btn, UI::Box::AlignLeft);
+
 	m_radiogroup.add_button
-		(this,
-		 pos,
+		(hbox2,
+		 Point(0, 0),
 		 g_gr->get_picture(PicMod_Game, "pics/genstats_casualties.png"),
-		 _("Casualties"));
-	pos.x += button_size + spacing;
+		 _("Casualties"),
+		 &btn);
+	hbox2->add(btn, UI::Box::AlignLeft);
+
 	m_radiogroup.add_button
-		(this,
-		 pos,
+		(hbox2,
+		 Point(0, 0),
 		 g_gr->get_picture(PicMod_Game, "pics/genstats_kills.png"),
-		 _("Kills"));
-	pos.x += button_size + spacing;
+		 _("Kills"),
+		 &btn);
+	hbox2->add(btn, UI::Box::AlignLeft);
+
 	m_radiogroup.add_button
-		(this,
-		 pos,
+		(hbox2,
+		 Point(0, 0),
 		 g_gr->get_picture(PicMod_Game, "pics/genstats_msites_lost.png"),
-		 _("Military buildings lost"));
-	pos.x += button_size + spacing;
+		 _("Military buildings lost"),
+		 &btn);
+	hbox2->add(btn, UI::Box::AlignLeft);
+
 	m_radiogroup.add_button
-		(this,
-		 pos,
+		(hbox2,
+		 Point(0, 0),
 		 g_gr->get_picture(PicMod_Game, "pics/genstats_msites_defeated.png"),
-		 _("Military buildings defeated"));
-	pos.x += button_size + spacing;
+		 _("Military buildings defeated"),
+		 &btn);
+	hbox2->add(btn, UI::Box::AlignLeft);
+
 	m_radiogroup.add_button
-		(this,
-		 pos,
+		(hbox2,
+		 Point(0, 0),
 		 g_gr->get_picture(PicMod_Game, "pics/genstats_civil_blds_lost.png"),
-		 _("Civilian buildings lost"));
-	pos.x += button_size + spacing;
+		 _("Civilian buildings lost"),
+		 &btn);
+	hbox2->add(btn, UI::Box::AlignLeft);
+
 	m_radiogroup.add_button
-		(this,
-		 pos,
+		(hbox2,
+		 Point(0, 0),
 		 g_gr->get_picture(PicMod_Game, "pics/genstats_militarystrength.png"),
-		 _("Military"));
+		 _("Military"),
+		 &btn);
+	hbox2->add(btn, UI::Box::AlignLeft);
+
 	if (hook) {
-		pos.x += button_size + spacing;
 		m_radiogroup.add_button
-			(this,
-			 pos,
+			(hbox2,
+			 Point(0, 0),
 			 g_gr->get_picture(PicMod_Game, cs_pic),
-			 cs_name.c_str());
+			 cs_name.c_str(),
+			 &btn);
+		hbox2->add(btn, UI::Box::AlignLeft);
 	}
+
 	m_radiogroup.set_state(0);
 	m_selected_information = 0;
 	m_radiogroup.changedto.set
 		(this, &General_Statistics_Menu::radiogroup_changed);
-	pos.y += 25;
-
-	pos.x = spacing;
-	pos.y += spacing + spacing;
-
-	new WUIPlot_Area_Slider
-		(this, m_plot,
-		 pos.x, pos.y, get_inner_w() - 2 * spacing, 45,
-		 g_gr->get_picture(PicMod_UI, "pics/but1.png"));
-
-	pos.y += 45 + spacing;
-
-	set_inner_size(get_inner_w(), pos.y);
+
+	m_box.add(hbox2, UI::Box::AlignTop);
+
+	m_box.add
+		(new WUIPlot_Area_Slider
+			(&m_box, m_plot, 0, 0, 100, 45,
+			 g_gr->get_picture(PicMod_UI, "pics/but1.png"))
+		, UI::Box::AlignTop
+		, true);
+
 }
 
 

=== modified file 'src/wui/general_statistics_menu.h'
--- src/wui/general_statistics_menu.h	2011-11-05 14:48:43 +0000
+++ src/wui/general_statistics_menu.h	2011-11-06 12:40:30 +0000
@@ -27,6 +27,7 @@
 #include "ui_basic/radiobutton.h"
 #include "ui_basic/button.h"
 #include "ui_basic/unique_window.h"
+#include "ui_basic/box.h"
 
 struct Interactive_GameBase;
 namespace UI {
@@ -38,6 +39,7 @@
 		(Interactive_GameBase &, UI::UniqueWindow::Registry &);
 
 private:
+	UI::Box              m_box;
 	WUIPlot_Area         m_plot;
 	UI::Radiogroup       m_radiogroup;
 	int32_t              m_selected_information;

=== modified file 'src/wui/plot_area.cc'
--- src/wui/plot_area.cc	2011-11-05 18:24:22 +0000
+++ src/wui/plot_area.cc	2011-11-06 12:40:30 +0000
@@ -58,7 +58,8 @@
 :
 UI::Panel (parent, x, y, w, h),
 m_time    (TIME_GAME),
-m_plotmode(PLOTMODE_ABSOLUTE)
+m_plotmode(PLOTMODE_ABSOLUTE),
+m_game_time_id(0)
 {}
 
 
@@ -115,6 +116,7 @@
 		case UNIT_HOUR: return _("h");
 		case UNIT_MIN:  return _("min");
 	}
+	return "invalid";
 }
 
 uint32_t WUIPlot_Area::ms_to_unit(UNIT unit, uint32_t ms) {
@@ -123,26 +125,31 @@
 		case UNIT_HOUR: return ms / hours;
 		case UNIT_MIN: return ms / minutes;
 	}
+	return -1;
 }
 
 std::vector<std::string> WUIPlot_Area::get_labels() {
 	std::vector<std::string> labels;
+	for (int32_t i = 0; i < m_game_time_id; i++) {
+		UNIT unit = get_suggested_unit(time_in_ms[i]);
+		uint32_t val = ms_to_unit(unit, time_in_ms[i]);
+		labels.push_back(boost::lexical_cast<std::string>(val) + get_unit_name(unit));
+	}
+	labels.push_back(_("game"));
+	return labels;
+}
+
+/**
+ * Find the last predefined time span that is less than the game time
+ */
+void WUIPlot_Area::calc_game_time_id() {
 	uint32_t game_time = get_game_time();
 	uint32_t i = 0;
-
-	for (i = 0; i < 7; i++) {
-		if (time_in_ms[i] < game_time) {
-			UNIT unit = get_suggested_unit(time_in_ms[i]);
-			uint32_t val = ms_to_unit(unit, time_in_ms[i]);
-			labels.push_back(boost::lexical_cast<std::string>(val) + get_unit_name(unit));
-		}
+	for (i = 0; i < 7 && time_in_ms[i] <= game_time; i++) {
 	}
-	labels.push_back(_("game"));
-	m_game_label = i;
-	return labels;
+	m_game_time_id = i;
 }
 
-
 /*
  * Draw this. This is the main function
  */
@@ -379,6 +386,8 @@
 	m_plotdata[id].dataset   = data;
 	m_plotdata[id].showplot  = false;
 	m_plotdata[id].plotcolor = color;
+
+	calc_game_time_id();
 }
 
 /*

=== modified file 'src/wui/plot_area.h'
--- src/wui/plot_area.h	2011-11-05 21:32:08 +0000
+++ src/wui/plot_area.h	2011-11-06 12:40:30 +0000
@@ -42,7 +42,6 @@
 		TIME_EIGHT_HOURS,
 		TIME_16_HOURS,
 		TIME_GAME,
-		TIME_LAST,
 	};
 	enum UNIT {
 		UNIT_MIN,
@@ -66,13 +65,14 @@
 		m_time = id;
 	}
 
-	void set_time_int(int32_t time) {
-		if (time == m_game_label)
+	void set_time_id(int32_t time) {
+		if (time == m_game_time_id)
 			set_time(TIME_GAME);
 		else
 			set_time(static_cast<TIME>(time));
 	};
 	TIME get_time() {return static_cast<TIME>(m_time); };
+	int32_t get_game_time_id() {return m_game_time_id; };
 	void set_sample_rate(uint32_t id); // in milliseconds
 
 	void register_plot_data
@@ -86,6 +86,7 @@
 private:
 	uint32_t get_game_time();
 	uint32_t get_plot_time();
+	void calc_game_time_id();
 	UNIT get_suggested_unit(uint32_t game_time);
 	std::string get_unit_name(UNIT unit);
 	uint32_t ms_to_unit(UNIT unit, uint32_t ms);
@@ -96,10 +97,10 @@
 		RGBColor                      plotcolor;
 	};
 	std::vector<__plotdata> m_plotdata;
-	int32_t                 m_time;  // How much do you want to list
+	TIME                    m_time;  // How much do you want to list
 	int32_t                 m_sample_rate;
 	int32_t                 m_plotmode;
-	int32_t                 m_game_label; // what label is used for TIME_GAME
+	int32_t                 m_game_time_id; // what label is used for TIME_GAME
 };
 
 /**
@@ -119,13 +120,13 @@
 		(parent,
 		 x, y, w, h,
 		 plot_area.get_labels(),
-		 plot_area.get_time(),
+		 plot_area.get_game_time_id(),
 		 background_picture_id,
 		 tooltip_text,
 		 cursor_size,
 		 enabled)
 	{
-		changedto->set(&plot_area, &WUIPlot_Area::set_time_int);
+		changedto->set(&plot_area, &WUIPlot_Area::set_time_id);
 	}
 };
 

=== modified file 'src/wui/ware_statistics_menu.cc'
--- src/wui/ware_statistics_menu.cc	2011-11-05 18:25:27 +0000
+++ src/wui/ware_statistics_menu.cc	2011-11-06 12:40:30 +0000
@@ -326,34 +326,18 @@
 {
 	set_cache(false);
 
-	//  First, we must decide about the size.
-	uint8_t const nr_wares = parent.get_player()->tribe().get_nrwares().value();
-
-#define spacing 5
-	Point const offs(spacing, 30);
-	Point       pos (offs);
-
-
-	// Setup Wares selectoin widget first, because the window size depends on it.
-	pos.y += PLOT_HEIGHT + 2 * spacing;
-	pos.x  = spacing;
-
-	StatisticWaresDisplay * swd =
-		new StatisticWaresDisplay
-			(this, spacing, pos.y, parent.get_player()->tribe(),
-			 boost::bind(&Ware_Statistics_Menu::cb_changed_to, boost::ref(*this), _1, _2));
-
-	pos.y += swd->get_h();
-	pos.y += spacing;
-
-	// Setup plot widget
-	m_plot =
-		new WUIPlot_Area
-			(this,
-			 spacing, offs.y + spacing, swd->get_w(), PLOT_HEIGHT);
+	UI::Box * box = new UI::Box(this, 0, 0, UI::Box::Vertical, 0, 0, 5);
+	box->set_border(5, 5, 5, 5);
+	set_center_panel(box);
+
+	m_plot = new WUIPlot_Area
+			(box, 0, 0, 100, PLOT_HEIGHT);
 	m_plot->set_sample_rate(STATISTICS_SAMPLE_TIME);
 	m_plot->set_plotmode(WUIPlot_Area::PLOTMODE_RELATIVE);
 
+	box->add(m_plot, UI::Box::AlignLeft, true);
+
+	uint8_t const nr_wares = parent.get_player()->tribe().get_nrwares().value();
 	for (Widelands::Ware_Index::value_t cur_ware = 0; cur_ware < nr_wares; ++cur_ware) {
 		m_plot->register_plot_data
 			(cur_ware,
@@ -362,15 +346,18 @@
 			 colors[cur_ware]);
 	}
 
-
-	new WUIPlot_Area_Slider
-		(this, *m_plot,
-		 pos.x, pos.y, swd->get_w(), 45,
-		 g_gr->get_picture(PicMod_UI, "pics/but1.png"));
-
-	pos.y += 45 + spacing;
-
-	set_inner_size(swd->get_w() + 2 * spacing, pos.y);
+	box->add
+		(new StatisticWaresDisplay
+			(box, 0, 0, parent.get_player()->tribe(),
+			 boost::bind(&Ware_Statistics_Menu::cb_changed_to, boost::ref(*this), _1, _2)),
+		 UI::Box::AlignLeft, true);
+
+
+	box->add
+		(new WUIPlot_Area_Slider
+			(box, *m_plot, 0, 0, 100, 45,
+			 g_gr->get_picture(PicMod_UI, "pics/but1.png")),
+		UI::Box::AlignLeft, true);
 }
 
 


Follow ups