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

Proposed by Joachim Breitner
Status: Merged
Merged at revision: 6064
Proposed branch: lp:~nomeata/widelands/plot-improvements
Merge into: lp:widelands
Diff against target: 499 lines (+202/-81)
6 files modified
src/ui_basic/button.h (+1/-0)
src/ui_basic/slider.cc (+13/-11)
src/wui/general_statistics_menu.cc (+20/-15)
src/wui/general_statistics_menu.h (+3/-3)
src/wui/plot_area.cc (+139/-46)
src/wui/plot_area.h (+26/-6)
To merge this branch: bzr merge lp:~nomeata/widelands/plot-improvements
Reviewer Review Type Date Requested Status
Widelands Developers Pending
Review via email: mp+81360@code.launchpad.net

Description of the change

Plot time slider offers only sensible times, automatically find a good choice of units and xticks, make units translatable and use buttons for the player selection.

To post a comment you must log in.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'src/ui_basic/button.h'
--- src/ui_basic/button.h 2011-11-04 18:22:20 +0000
+++ src/ui_basic/button.h 2011-11-05 14:59:26 +0000
@@ -79,6 +79,7 @@
7979
80 // Set the permanently pressed state of the button80 // Set the permanently pressed state of the button
81 void set_perm_pressed(bool state);81 void set_perm_pressed(bool state);
82 bool get_perm_pressed() const { return m_permpressed;}
8283
83 // Set button to flat / not flat84 // Set button to flat / not flat
84 void set_flat(bool flat);85 void set_flat(bool flat);
8586
=== modified file 'src/ui_basic/slider.cc'
--- src/ui_basic/slider.cc 2011-11-04 21:42:45 +0000
+++ src/ui_basic/slider.cc 2011-11-05 14:59:26 +0000
@@ -380,18 +380,20 @@
380{380{
381 RGBAColor black(0, 0, 0, 255);381 RGBAColor black(0, 0, 0, 255);
382382
383 dst.brighten_rect // bottom edge383 if (get_bar_size() > 0) {
384 (Rect(Point(get_x_gap(), get_h() / 2), get_bar_size(), 2),384 dst.brighten_rect // bottom edge
385 BUTTON_EDGE_BRIGHT_FACTOR);385 (Rect(Point(get_x_gap(), get_h() / 2), get_bar_size(), 2),
386 dst.brighten_rect // right edge386 BUTTON_EDGE_BRIGHT_FACTOR);
387 (Rect(Point(get_x_gap() + get_bar_size() - 2, get_y_gap()), 2, 2),387 dst.brighten_rect // right edge
388 BUTTON_EDGE_BRIGHT_FACTOR);388 (Rect(Point(get_x_gap() + get_bar_size() - 2, get_y_gap()), 2, 2),
389 BUTTON_EDGE_BRIGHT_FACTOR);
389390
390 // top edge391 // top edge
391 dst.fill_rect392 dst.fill_rect
392 (Rect(Point(get_x_gap(), get_y_gap()), get_bar_size() - 1, 1), black);393 (Rect(Point(get_x_gap(), get_y_gap()), get_bar_size() - 1, 1), black);
393 dst.fill_rect394 dst.fill_rect
394 (Rect(Point(get_x_gap(), get_y_gap() + 1), get_bar_size() - 2, 1), black);395 (Rect(Point(get_x_gap(), get_y_gap() + 1), get_bar_size() - 2, 1), black);
396 }
395397
396 // left edge398 // left edge
397 dst.fill_rect(Rect(Point(get_x_gap(), get_y_gap()), 1, 4), black);399 dst.fill_rect(Rect(Point(get_x_gap(), get_y_gap()), 1, 4), black);
398400
=== modified file 'src/wui/general_statistics_menu.cc'
--- src/wui/general_statistics_menu.cc 2011-11-04 22:07:49 +0000
+++ src/wui/general_statistics_menu.cc 2011-11-05 14:59:26 +0000
@@ -129,28 +129,30 @@
129 iterate_players_existing_const(p, nr_players, game, player) ++plr_in_game;129 iterate_players_existing_const(p, nr_players, game, player) ++plr_in_game;
130130
131 pos.x = spacing;131 pos.x = spacing;
132 int32_t button_size =
133 (get_inner_w() - (spacing * (plr_in_game + 1))) / plr_in_game;
134 iterate_players_existing_const(p, nr_players, game, player) {132 iterate_players_existing_const(p, nr_players, game, player) {
135 char buffer[36];133 char buffer[36];
136 snprintf(buffer, sizeof(buffer), "pics/genstats_enable_plr_%02u.png", p);134 snprintf(buffer, sizeof(buffer), "pics/genstats_enable_plr_%02u.png", p);
137 UI::Checkbox & cb =135 UI::Callback_Button & cb =
138 *new UI::Checkbox136 *new UI::Callback_Button
139 (this, pos, g_gr->get_picture(PicMod_Game, buffer));137 (this, "playerbutton",
140 cb.set_size(button_size, 25);138 pos.x, pos.y, 25, 25,
141 cb.set_id(p);139 g_gr->get_picture(PicMod_UI, "pics/but4.png"),
142 cb.set_state(1);140 g_gr->get_picture(PicMod_Game, buffer),
143 cb.set_tooltip(player->get_name().c_str());141 boost::bind
144 cb.changedtoid.set(this, &General_Statistics_Menu::cb_changed_to);142 (&General_Statistics_Menu::cb_changed_to,
143 boost::ref(*this),
144 p),
145 player->get_name().c_str());
146 cb.set_perm_pressed(true);
145 m_cbs[p - 1] = &cb;147 m_cbs[p - 1] = &cb;
146 pos.x += button_size + spacing;148 pos.x += 25 + spacing;
147 } else // player nr p does not exist149 } else // player nr p does not exist
148 m_cbs[p - 1] = 0;150 m_cbs[p - 1] = 0;
149151
150 pos.x = spacing;152 pos.x = spacing;
151 pos.y += 25 + spacing + spacing;153 pos.y += 25 + spacing + spacing;
152154
153 button_size =155 int32_t button_size =
154 (get_inner_w() - spacing * (m_ndatasets + 1))156 (get_inner_w() - spacing * (m_ndatasets + 1))
155 /157 /
156 m_ndatasets;158 m_ndatasets;
@@ -257,11 +259,14 @@
257/*259/*
258 * Cb has been changed to this state260 * Cb has been changed to this state
259 */261 */
260void General_Statistics_Menu::cb_changed_to(int32_t const id, bool const what)262void General_Statistics_Menu::cb_changed_to(int32_t const id)
261{263{
262 // This represents our player number264 // This represents our player number
265 m_cbs[id - 1]->set_perm_pressed(not m_cbs[id - 1]->get_perm_pressed());
266
263 m_plot.show_plot267 m_plot.show_plot
264 ((id - 1) * m_ndatasets + m_selected_information, what);268 ((id - 1) * m_ndatasets + m_selected_information,
269 m_cbs[id - 1]->get_perm_pressed());
265}270}
266271
267/*272/*
@@ -274,7 +279,7 @@
274 for (uint32_t i = 0; i < statistics_size; ++i)279 for (uint32_t i = 0; i < statistics_size; ++i)
275 if (m_cbs[i]) {280 if (m_cbs[i]) {
276 m_plot.show_plot281 m_plot.show_plot
277 (i * m_ndatasets + id, m_cbs[i]->get_state());282 (i * m_ndatasets + id, m_cbs[i]->get_perm_pressed());
278 m_plot.show_plot283 m_plot.show_plot
279 (i * m_ndatasets + m_selected_information, false);284 (i * m_ndatasets + m_selected_information, false);
280 }285 }
281286
=== modified file 'src/wui/general_statistics_menu.h'
--- src/wui/general_statistics_menu.h 2010-09-04 13:50:09 +0000
+++ src/wui/general_statistics_menu.h 2011-11-05 14:59:26 +0000
@@ -25,11 +25,11 @@
25#include "plot_area.h"25#include "plot_area.h"
2626
27#include "ui_basic/radiobutton.h"27#include "ui_basic/radiobutton.h"
28#include "ui_basic/button.h"
28#include "ui_basic/unique_window.h"29#include "ui_basic/unique_window.h"
2930
30struct Interactive_GameBase;31struct Interactive_GameBase;
31namespace UI {32namespace UI {
32struct Checkbox;
33struct Radiogroup;33struct Radiogroup;
34}34}
3535
@@ -41,11 +41,11 @@
41 WUIPlot_Area m_plot;41 WUIPlot_Area m_plot;
42 UI::Radiogroup m_radiogroup;42 UI::Radiogroup m_radiogroup;
43 int32_t m_selected_information;43 int32_t m_selected_information;
44 UI::Checkbox * m_cbs[MAX_PLAYERS];44 UI::Callback_Button * m_cbs[MAX_PLAYERS];
45 uint32_t m_ndatasets;45 uint32_t m_ndatasets;
4646
47 void clicked_help();47 void clicked_help();
48 void cb_changed_to(int32_t, bool);48 void cb_changed_to(int32_t);
49 void radiogroup_changed(int32_t);49 void radiogroup_changed(int32_t);
50};50};
5151
5252
=== modified file 'src/wui/plot_area.cc'
--- src/wui/plot_area.cc 2011-11-04 22:07:49 +0000
+++ src/wui/plot_area.cc 2011-11-05 14:59:26 +0000
@@ -19,48 +19,31 @@
1919
20#include "plot_area.h"20#include "plot_area.h"
2121
22#include "i18n.h"
22#include "constants.h"23#include "constants.h"
23#include "graphic/font.h"24#include "graphic/font.h"
24#include "graphic/font_handler.h"25#include "graphic/font_handler.h"
25#include "graphic/graphic.h"26#include "graphic/graphic.h"
26#include "graphic/rendertarget.h"27#include "graphic/rendertarget.h"
2728
29
28#include "ui_basic/panel.h"30#include "ui_basic/panel.h"
2931
30#include <cstdio>32#include <cstdio>
3133#include <boost/lexical_cast.hpp>
3234
33/*35static const uint32_t minutes = 60 * 1000;
34 * Where to draw tics36static const uint32_t hours = 60 * 60 * 1000;
35 */37static const uint32_t days = 24 * 60 * 60 * 1000;
36static const int32_t how_many_ticks[] = {
37 5, // 15 Mins
38 3, // 30 Mins
39 6, // 1 H
40 4, // 2 H
41 4, // 4 H
42 4, // 8 H
43 4, // 16 H
44};
45
46static const int32_t max_x[] = {
47 15,
48 30,
49 60,
50 120,
51 4,
52 8,
53 16
54};
5538
56static const uint32_t time_in_ms[] = {39static const uint32_t time_in_ms[] = {
57 15 * 60 * 1000,40 15 * minutes,
58 30 * 60 * 1000,41 30 * minutes,
59 1 * 60 * 60 * 1000,42 1 * hours,
60 2 * 60 * 60 * 1000,43 2 * hours,
61 4 * 60 * 60 * 1000,44 5 * hours,
62 8 * 60 * 60 * 1000,45 10 * hours,
63 16 * 60 * 60 * 1000,46 30 * hours
64};47};
6548
66#define NR_SAMPLES 30 // How many samples per diagramm when relative plotting49#define NR_SAMPLES 30 // How many samples per diagramm when relative plotting
@@ -74,16 +57,128 @@
74 int32_t const x, int32_t const y, int32_t const w, int32_t const h)57 int32_t const x, int32_t const y, int32_t const w, int32_t const h)
75:58:
76UI::Panel (parent, x, y, w, h),59UI::Panel (parent, x, y, w, h),
77m_time (TIME_ONE_HOUR),60m_time (TIME_GAME),
78m_plotmode(PLOTMODE_ABSOLUTE)61m_plotmode(PLOTMODE_ABSOLUTE)
79{}62{}
8063
8164
65uint32_t WUIPlot_Area::get_game_time() {
66 uint32_t game_time = 0;
67
68 // Find running time of the game, based on the plot data
69 for (uint32_t plot = 0; plot < m_plotdata.size(); ++plot)
70 if (game_time < m_plotdata[plot].dataset->size() * m_sample_rate)
71 game_time = m_plotdata[plot].dataset->size() * m_sample_rate;
72 return game_time;
73}
74
75uint32_t WUIPlot_Area::get_plot_time() {
76 if (m_time == TIME_GAME) {
77 // Start with the game time
78 uint32_t time_in_ms_ = get_game_time();
79
80 // Round up to a nice nearest multiple.
81 // Either a multiple of 4 min
82 // Either a multiple of 20 min
83 // or a multiple of 2h
84 // or a multiple of 20h
85 // or a multiple of 4 days
86 if (time_in_ms_ > 8 * days) {
87 time_in_ms_ += - (time_in_ms_ % (4 * days)) + 4 * days;
88 } else if (time_in_ms_ > 40 * hours) {
89 time_in_ms_ += - (time_in_ms_ % (20 * hours)) + 20 * hours;
90 } else if (time_in_ms_ > 4 * hours) {
91 time_in_ms_ += - (time_in_ms_ % (2 * hours)) + 2 * hours;
92 } else if (time_in_ms_ > 40 * minutes) {
93 time_in_ms_ += - (time_in_ms_ % (20 * minutes)) + 20 * minutes;
94 } else {
95 time_in_ms_ += - (time_in_ms_ % (4 * minutes)) + 5 * minutes;
96 }
97 return time_in_ms_;
98 } else {
99 return time_in_ms[m_time];
100 }
101}
102
103WUIPlot_Area::UNIT WUIPlot_Area::get_suggested_unit(uint32_t game_time) {
104 // Find a nice unit for max_x
105 if (game_time > 4 * days) {
106 return UNIT_DAY;
107 } else if (game_time > 4 * hours) {
108 return UNIT_HOUR;
109 } else {
110 return UNIT_MIN;
111 }
112}
113
114std::string WUIPlot_Area::get_unit_name(UNIT unit) {
115 switch (unit) {
116 case UNIT_DAY: return _("d");
117 case UNIT_HOUR: return _("h");
118 case UNIT_MIN: return _("min");
119 }
120}
121
122uint32_t WUIPlot_Area::ms_to_unit(UNIT unit, uint32_t ms) {
123 switch (unit) {
124 case UNIT_DAY: return ms / days;
125 case UNIT_HOUR: return ms / hours;
126 case UNIT_MIN: return ms / minutes;
127 }
128}
129
130std::vector<std::string> WUIPlot_Area::get_labels() {
131 std::vector<std::string> labels;
132 uint32_t game_time = get_game_time();
133 uint32_t i = 0;
134
135 for (i = 0; i < 7; i++) {
136 if (time_in_ms[i] < game_time) {
137 UNIT unit = get_suggested_unit(time_in_ms[i]);
138 uint32_t val = ms_to_unit(unit, time_in_ms[i]);
139 labels.push_back(boost::lexical_cast<std::string>(val) + get_unit_name(unit));
140 }
141 }
142 labels.push_back(_("game"));
143 m_game_label = i;
144 return labels;
145}
146
147
82/*148/*
83 * Draw this. This is the main function149 * Draw this. This is the main function
84 */150 */
85void WUIPlot_Area::draw(RenderTarget & dst) {151void WUIPlot_Area::draw(RenderTarget & dst) {
86152
153 uint32_t time_in_ms_, how_many_ticks, max_x;
154
155 time_in_ms_ = get_plot_time();
156 UNIT unit = get_suggested_unit(time_in_ms_);
157 max_x = ms_to_unit(unit, time_in_ms_);
158
159 // Find a nice division of max_x
160 if (max_x % 5 == 0) {
161 if (max_x <= 10) {
162 how_many_ticks = 5;
163 } else {
164 how_many_ticks = max_x / 5;
165 while (how_many_ticks > 7 && how_many_ticks % 2 == 0) {
166 how_many_ticks /= 2;
167 }
168 while (how_many_ticks > 7 && how_many_ticks % 3 == 0) {
169 how_many_ticks /= 3;
170 }
171 while (how_many_ticks > 7 && how_many_ticks % 5 == 0) {
172 how_many_ticks /= 5;
173 }
174 while (how_many_ticks > 7 && how_many_ticks % 7 == 0) {
175 how_many_ticks /= 7;
176 }
177 }
178 } else {
179 how_many_ticks = 4;
180 }
181
87 // first, tile the background182 // first, tile the background
88 dst.tile183 dst.tile
89 (Rect(Point(0, 0), get_inner_w(), get_inner_h()),184 (Rect(Point(0, 0), get_inner_w(), get_inner_h()),
@@ -123,10 +218,10 @@
123 UI::TextStyle xtickstyle(UI::TextStyle::ui_small());218 UI::TextStyle xtickstyle(UI::TextStyle::ui_small());
124 xtickstyle.fg = RGBColor(255, 0, 0);219 xtickstyle.fg = RGBColor(255, 0, 0);
125220
126 float sub = xline_length / how_many_ticks[m_time];221 float sub = xline_length / how_many_ticks;
127 float posx = get_inner_w() - space_at_right;222 float posx = get_inner_w() - space_at_right;
128 char buffer[200];223 char buffer[200];
129 for (int32_t i = 0; i <= how_many_ticks[m_time]; ++i) {224 for (uint32_t i = 0; i <= how_many_ticks; ++i) {
130 dst.draw_line225 dst.draw_line
131 (static_cast<int32_t>(posx), get_inner_h() - space_at_bottom,226 (static_cast<int32_t>(posx), get_inner_h() - space_at_bottom,
132 static_cast<int32_t>(posx), get_inner_h() - space_at_bottom + 3,227 static_cast<int32_t>(posx), get_inner_h() - space_at_bottom + 3,
@@ -134,7 +229,7 @@
134229
135 snprintf230 snprintf
136 (buffer, sizeof(buffer),231 (buffer, sizeof(buffer),
137 "%u", max_x[m_time] / how_many_ticks[m_time] * i);232 "%u", max_x / how_many_ticks * i);
138233
139 UI::g_fh->draw_text234 UI::g_fh->draw_text
140 (dst, xtickstyle,235 (dst, xtickstyle,
@@ -176,7 +271,7 @@
176 // How many do we take together271 // How many do we take together
177 int32_t const how_many =272 int32_t const how_many =
178 static_cast<int32_t>273 static_cast<int32_t>
179 ((static_cast<float>(time_in_ms[m_time])274 ((static_cast<float>(time_in_ms_)
180 /275 /
181 static_cast<float>(NR_SAMPLES))276 static_cast<float>(NR_SAMPLES))
182 /277 /
@@ -205,11 +300,17 @@
205 Point(get_inner_w() - space_at_right - 2, spacing + 2),300 Point(get_inner_w() - space_at_right - 2, spacing + 2),
206 buffer, UI::Align_CenterRight);301 buffer, UI::Align_CenterRight);
207302
303 // print the used unit
304 UI::g_fh->draw_text
305 (dst, xtickstyle,
306 Point(2, spacing + 2),
307 get_unit_name(unit), UI::Align_CenterLeft);
308
208 // plot the pixels309 // plot the pixels
209 sub =310 sub =
210 xline_length311 xline_length
211 /312 /
212 (static_cast<float>(time_in_ms[m_time])313 (static_cast<float>(time_in_ms_)
213 /314 /
214 static_cast<float>(m_sample_rate));315 static_cast<float>(m_sample_rate));
215 for (uint32_t plot = 0; plot < m_plotdata.size(); ++plot)316 for (uint32_t plot = 0; plot < m_plotdata.size(); ++plot)
@@ -222,7 +323,7 @@
222 if (m_plotmode == PLOTMODE_RELATIVE) {323 if (m_plotmode == PLOTMODE_RELATIVE) {
223 // How many do we take together.324 // How many do we take together.
224 const int32_t how_many = static_cast<int32_t>325 const int32_t how_many = static_cast<int32_t>
225 ((static_cast<float>(time_in_ms[m_time])326 ((static_cast<float>(time_in_ms_)
226 /327 /
227 static_cast<float>(NR_SAMPLES))328 static_cast<float>(NR_SAMPLES))
228 /329 /
@@ -292,17 +393,9 @@
292};393};
293394
294/*395/*
295 * set time
296 */
297void WUIPlot_Area::set_time(TIME const id) {m_time = id;}
298
299/*
300 * Set sample rate the data uses396 * Set sample rate the data uses
301 */397 */
302void WUIPlot_Area::set_sample_rate(uint32_t const id) {398void WUIPlot_Area::set_sample_rate(uint32_t const id) {
303 m_sample_rate = id;399 m_sample_rate = id;
304}400}
305401
306std::string WUIPlot_Area::time_labels[WUIPlot_Area::TIME_LAST] =
307 {"15m", "30m", "1h", "2h", "4h", "8h", "16h"};
308
309402
=== modified file 'src/wui/plot_area.h'
--- src/wui/plot_area.h 2011-11-04 22:07:49 +0000
+++ src/wui/plot_area.h 2011-11-05 14:59:26 +0000
@@ -41,9 +41,14 @@
41 TIME_FOUR_HOURS,41 TIME_FOUR_HOURS,
42 TIME_EIGHT_HOURS,42 TIME_EIGHT_HOURS,
43 TIME_16_HOURS,43 TIME_16_HOURS,
44 TIME_GAME,
44 TIME_LAST,45 TIME_LAST,
45 };46 };
46 static std::string time_labels[TIME_LAST];47 enum UNIT {
48 UNIT_MIN,
49 UNIT_HOUR,
50 UNIT_DAY,
51 };
47 enum PLOTMODE {52 enum PLOTMODE {
48 // Always take the samples of some times together, so that the graph is53 // Always take the samples of some times together, so that the graph is
49 // not completely zigg-zagged.54 // not completely zigg-zagged.
@@ -57,8 +62,16 @@
5762
58 virtual void draw(RenderTarget &);63 virtual void draw(RenderTarget &);
5964
60 void set_time(TIME);65 void set_time(TIME id) {
61 void set_time_int(int32_t time) {set_time(static_cast<TIME>(time)); };66 m_time = id;
67 }
68
69 void set_time_int(int32_t time) {
70 if (time == m_game_label)
71 set_time(TIME_GAME);
72 else
73 set_time(static_cast<TIME>(time));
74 };
62 TIME get_time() {return static_cast<TIME>(m_time); };75 TIME get_time() {return static_cast<TIME>(m_time); };
63 void set_sample_rate(uint32_t id); // in milliseconds76 void set_sample_rate(uint32_t id); // in milliseconds
6477
@@ -68,7 +81,15 @@
6881
69 void set_plotmode(int32_t id) {m_plotmode = id;}82 void set_plotmode(int32_t id) {m_plotmode = id;}
7083
84 std::vector<std::string> get_labels();
85
71private:86private:
87 uint32_t get_game_time();
88 uint32_t get_plot_time();
89 UNIT get_suggested_unit(uint32_t game_time);
90 std::string get_unit_name(UNIT unit);
91 uint32_t ms_to_unit(UNIT unit, uint32_t ms);
92
72 struct __plotdata {93 struct __plotdata {
73 const std::vector<uint32_t> * dataset;94 const std::vector<uint32_t> * dataset;
74 bool showplot;95 bool showplot;
@@ -78,6 +99,7 @@
78 int32_t m_time; // How much do you want to list99 int32_t m_time; // How much do you want to list
79 int32_t m_sample_rate;100 int32_t m_sample_rate;
80 int32_t m_plotmode;101 int32_t m_plotmode;
102 int32_t m_game_label; // what label is used for TIME_GAME
81};103};
82104
83/**105/**
@@ -96,9 +118,7 @@
96 : DiscreteSlider118 : DiscreteSlider
97 (parent,119 (parent,
98 x, y, w, h,120 x, y, w, h,
99 std::vector<std::string>121 plot_area.get_labels(),
100 (WUIPlot_Area::time_labels,
101 WUIPlot_Area::time_labels + WUIPlot_Area::TIME_LAST),
102 plot_area.get_time(),122 plot_area.get_time(),
103 background_picture_id,123 background_picture_id,
104 tooltip_text,124 tooltip_text,

Subscribers

People subscribed via source and target branches

to status/vote changes: