Merge lp:~widelands-dev/widelands/ui_improvments into lp:widelands

Proposed by cghislai on 2013-07-16
Status: Merged
Merged at revision: 6629
Proposed branch: lp:~widelands-dev/widelands/ui_improvments
Merge into: lp:widelands
Diff against target: 1269 lines (+309/-216)
36 files modified
src/chat.h (+6/-0)
src/constants.h (+1/-1)
src/debugconsole.cc (+4/-0)
src/gamecontroller.cc (+31/-3)
src/logic/building.cc (+6/-0)
src/logic/building.h (+5/-0)
src/logic/production_program.cc (+2/-2)
src/logic/productionsite.cc (+1/-1)
src/logic/trainingsite.cc (+1/-6)
src/network/internet_gaming.cc (+8/-1)
src/network/internet_gaming.h (+3/-0)
src/network/netclient.cc (+9/-0)
src/network/netclient.h (+1/-0)
src/network/nethost.cc (+7/-0)
src/save_handler.cc (+10/-2)
src/timestring.cc (+15/-0)
src/timestring.h (+5/-0)
src/ui_basic/progressbar.cc (+9/-12)
src/ui_basic/table.cc (+11/-22)
src/ui_fsmenu/loadgame.cc (+3/-8)
src/ui_fsmenu/loadreplay.cc (+3/-8)
src/ui_fsmenu/mapselect.cc (+3/-3)
src/wlapplication.cc (+7/-5)
src/wui/building_ui.cc (+8/-1)
src/wui/buildingwindow.cc (+5/-46)
src/wui/buildingwindow.h (+0/-1)
src/wui/fieldaction.cc (+1/-43)
src/wui/game_main_menu_save_game.cc (+20/-13)
src/wui/game_main_menu_save_game.h (+1/-1)
src/wui/game_message_menu.cc (+5/-13)
src/wui/interactive_base.cc (+64/-0)
src/wui/interactive_base.h (+3/-0)
src/wui/interactive_player.cc (+13/-10)
src/wui/interactive_player.h (+3/-0)
src/wui/productionsitewindow.cc (+34/-13)
src/wui/productionsitewindow.h (+1/-1)
To merge this branch: bzr merge lp:~widelands-dev/widelands/ui_improvments
Reviewer Review Type Date Requested Status
SirVer 2013-07-16 Approve on 2013-07-17
Review via email: mp+175090@code.launchpad.net

Description of the change

Some fixes and features related to ui. See linked bugs and commit messages for details.
I tried to make commits as atomic as possible, so they could be merged separately if needed.

To post a comment you must log in.
SirVer (sirver) wrote :

No complaints from my site. Merged!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added file 'pics/workarea12.png'
2Binary files pics/workarea12.png 1970-01-01 00:00:00 +0000 and pics/workarea12.png 2013-07-16 17:39:34 +0000 differ
3=== added file 'pics/workarea123.png'
4Binary files pics/workarea123.png 1970-01-01 00:00:00 +0000 and pics/workarea123.png 2013-07-16 17:39:34 +0000 differ
5=== removed file 'pics/workarea1cumulative.png'
6Binary files pics/workarea1cumulative.png 2005-12-29 01:10:07 +0000 and pics/workarea1cumulative.png 1970-01-01 00:00:00 +0000 differ
7=== added file 'pics/workarea23.png'
8Binary files pics/workarea23.png 1970-01-01 00:00:00 +0000 and pics/workarea23.png 2013-07-16 17:39:34 +0000 differ
9=== removed file 'pics/workarea2cumulative.png'
10Binary files pics/workarea2cumulative.png 2005-12-29 01:10:07 +0000 and pics/workarea2cumulative.png 1970-01-01 00:00:00 +0000 differ
11=== removed file 'pics/workarea3cumulative.png'
12Binary files pics/workarea3cumulative.png 2009-11-09 19:01:11 +0000 and pics/workarea3cumulative.png 1970-01-01 00:00:00 +0000 differ
13=== modified file 'src/chat.h'
14--- src/chat.h 2013-02-10 19:36:24 +0000
15+++ src/chat.h 2013-07-16 17:39:34 +0000
16@@ -106,6 +106,12 @@
17 virtual void send(const std::string &) = 0;
18
19 /**
20+ * Sends the given message to the local player only
21+ * This may be used to display useful log messages.
22+ */
23+ virtual void send_local(const std::string &) = 0;
24+
25+ /**
26 * \return a (chronological) list of received chat messages.
27 * This list need not be stable or monotonic. In other words,
28 * subsequent calls to this functions may return a smaller or
29
30=== modified file 'src/constants.h'
31--- src/constants.h 2013-07-13 14:32:49 +0000
32+++ src/constants.h 2013-07-16 17:39:34 +0000
33@@ -131,7 +131,7 @@
34 * C++ is really bad at integer types. For example this constant is not
35 * recognized as a valid value of type Workarea_Info::size_type without a cast.
36 */
37-#define NUMBER_OF_WORKAREA_PICS static_cast<Workarea_Info::size_type>(3)
38+#define NUMBER_OF_WORKAREA_PICS static_cast<Workarea_Info::size_type>(6)
39
40 /// The size of the transient (i.e. temporary) surfaces in the cache in bytes.
41 /// These are all surfaces that are not loaded from disk.
42
43=== modified file 'src/debugconsole.cc'
44--- src/debugconsole.cc 2013-02-10 19:36:24 +0000
45+++ src/debugconsole.cc 2013-07-16 17:39:34 +0000
46@@ -85,6 +85,10 @@
47 it->second(arg);
48 }
49
50+ void send_local(const std::string& msg) {
51+ send(msg);
52+ }
53+
54 const std::vector<ChatMessage> & getMessages() const
55 {
56 return messages;
57
58=== modified file 'src/gamecontroller.cc'
59--- src/gamecontroller.cc 2012-02-15 21:25:34 +0000
60+++ src/gamecontroller.cc 2013-07-16 17:39:34 +0000
61@@ -25,8 +25,10 @@
62 #include "logic/playercommand.h"
63 #include "profile/profile.h"
64 #include "wlapplication.h"
65+#include "chat.h"
66+#include "wui/interactive_player.h"
67
68-struct SinglePlayerGameController : public GameController {
69+struct SinglePlayerGameController : public GameController, public ChatProvider {
70 SinglePlayerGameController
71 (Widelands::Game &, bool useai, Widelands::Player_Number local);
72 ~SinglePlayerGameController();
73@@ -42,6 +44,10 @@
74 bool isPaused();
75 void setPaused(bool paused);
76
77+ // Chat provider implementation
78+ void send(const std::string & msg);
79+ void send_local(const std::string & msg);
80+ const std::vector<ChatMessage> & getMessages() const;
81 private:
82 Widelands::Game & m_game;
83 bool m_useai;
84@@ -52,13 +58,14 @@
85 uint32_t m_player_cmdserial;
86 Widelands::Player_Number m_local;
87 std::vector<Computer_Player *> m_computerplayers;
88+ std::vector<ChatMessage> m_chatmessages;
89 };
90
91 SinglePlayerGameController::SinglePlayerGameController
92 (Widelands::Game & game,
93 bool const useai,
94 Widelands::Player_Number const local)
95- :
96+ : ChatProvider(),
97 m_game (game),
98 m_useai (useai),
99 m_lastframe (WLApplication::get()->get_time()),
100@@ -156,10 +163,31 @@
101 m_paused = paused;
102 }
103
104+void SinglePlayerGameController::send_local(const std::string& msg)
105+{
106+ ChatMessage c;
107+ c.msg = msg;
108+ c.time = time(0);
109+ m_chatmessages.push_back(c);
110+ ChatProvider::send(c);
111+}
112+
113+void SinglePlayerGameController::send(const std::string& msg)
114+{
115+ log("SinglePlayerGameController:: Cannot send chat messages in single player game!");
116+}
117+
118+const std::vector< ChatMessage >& SinglePlayerGameController::getMessages() const
119+{
120+ return m_chatmessages;
121+}
122+
123 GameController * GameController::createSinglePlayer
124 (Widelands::Game & game,
125 bool const cpls,
126 Widelands::Player_Number const local)
127 {
128- return new SinglePlayerGameController(game, cpls, local);
129+ SinglePlayerGameController* spgc = new SinglePlayerGameController(game, cpls, local);
130+ game.get_ipl()->set_chat_provider(*spgc);
131+ return spgc;
132 }
133
134=== modified file 'src/logic/building.cc'
135--- src/logic/building.cc 2013-07-14 10:38:26 +0000
136+++ src/logic/building.cc 2013-07-16 17:39:34 +0000
137@@ -19,6 +19,7 @@
138
139 #include <cstdio>
140 #include <sstream>
141+#include <boost/foreach.hpp>
142
143 #include "upcast.h"
144 #include "wexception.h"
145@@ -436,6 +437,9 @@
146 }
147
148 PlayerImmovable::cleanup(egbase);
149+
150+ BOOST_FOREACH(boost::signals::connection& c, options_window_connections)
151+ c.disconnect();
152 }
153
154
155@@ -855,6 +859,7 @@
156 set_seeing(true);
157 }
158 PlayerImmovable::add_worker(worker);
159+ workers_changed();
160 }
161
162
163@@ -862,6 +867,7 @@
164 PlayerImmovable::remove_worker(worker);
165 if (not get_workers().size())
166 set_seeing(false);
167+ workers_changed();
168 }
169
170 /**
171
172=== modified file 'src/logic/building.h'
173--- src/logic/building.h 2013-07-14 10:38:26 +0000
174+++ src/logic/building.h 2013-07-16 17:39:34 +0000
175@@ -34,6 +34,7 @@
176 #include <string>
177 #include <cstring>
178 #include <vector>
179+#include <boost/signal.hpp>
180
181 namespace UI {class Window;}
182 struct BuildingHints;
183@@ -223,6 +224,7 @@
184
185 void add_worker(Worker &);
186 void remove_worker(Worker &);
187+ mutable boost::signal<void ()> workers_changed;
188
189 void send_message
190 (Game & game,
191@@ -268,6 +270,9 @@
192
193 /// Whether we see our vision_range area based on workers in the building
194 bool m_seeing;
195+
196+ // Signals connected for the option window
197+ std::vector<boost::signals::connection> options_window_connections;
198 };
199
200 }
201
202=== modified file 'src/logic/production_program.cc'
203--- src/logic/production_program.cc 2013-04-27 16:55:46 +0000
204+++ src/logic/production_program.cc 2013-07-16 17:39:34 +0000
205@@ -1288,7 +1288,7 @@
206 snprintf
207 (ps.m_result_buffer, sizeof(ps.m_result_buffer),
208 _("No soldier for this training level found!"));
209- return ps.program_end(game, Failed);
210+ return ps.program_end(game, Skipped);
211 }
212 if (attribute == atrHP) {
213 if ((*it)->get_hp_level() == level)
214@@ -1378,7 +1378,7 @@
215 snprintf
216 (ps.m_result_buffer, sizeof(ps.m_result_buffer),
217 _("No soldier for this training level found!"));
218- return ps.program_end(game, Failed);
219+ return ps.program_end(game, Skipped);
220 }
221 if (attribute == atrHP) {
222 if ((*it)->get_hp_level () == level)
223
224=== modified file 'src/logic/productionsite.cc'
225--- src/logic/productionsite.cc 2013-05-25 09:30:35 +0000
226+++ src/logic/productionsite.cc 2013-07-16 17:39:34 +0000
227@@ -457,7 +457,6 @@
228
229 if (upcast(Game, game, &egbase))
230 try_start_working(*game);
231-
232 return 0;
233 }
234
235@@ -874,6 +873,7 @@
236 for (uint32_t i = descr().nr_working_positions(); i;)
237 m_working_positions[--i].worker->gain_experience(game);
238 m_result_buffer[0] = '\0';
239+ Building::workers_changed();
240 }
241 calc_statistics();
242 break;
243
244=== modified file 'src/logic/trainingsite.cc'
245--- src/logic/trainingsite.cc 2013-06-16 16:29:48 +0000
246+++ src/logic/trainingsite.cc 2013-07-16 17:39:34 +0000
247@@ -192,12 +192,7 @@
248 */
249 std::string TrainingSite::get_statistics_string()
250 {
251- if (State * const state = get_state())
252- return state->program->descname();
253- else if (m_result == Completed)
254- return _("Resting");
255- else
256- return _("Not Working");
257+ return ProductionSite::get_statistics_string();
258 }
259
260 /**
261
262=== modified file 'src/network/internet_gaming.cc'
263--- src/network/internet_gaming.cc 2013-04-20 20:20:34 +0000
264+++ src/network/internet_gaming.cc 2013-07-16 17:39:34 +0000
265@@ -768,7 +768,14 @@
266 s.send(m_sock);
267 }
268
269-
270+void InternetGaming::send_local(const std::string& msg)
271+{
272+ ChatMessage c;
273+ c.msg = msg;
274+ c.time = time(0);
275+ messages.push_back(c);
276+ ChatProvider::send(c);
277+}
278
279 /**
280 * \returns the boolean value of a string received from the metaserver.
281
282=== modified file 'src/network/internet_gaming.h'
283--- src/network/internet_gaming.h 2013-02-10 19:36:24 +0000
284+++ src/network/internet_gaming.h 2013-07-16 17:39:34 +0000
285@@ -114,6 +114,9 @@
286 // ChatProvider: sends a message via the metaserver.
287 void send(const std::string &);
288
289+ // ChatProvider: sends local messages
290+ void send_local(const std::string &);
291+
292 /// ChatProvider: adds the message to the message list and calls parent.
293 void receive(const ChatMessage & msg) {messages.push_back(msg); ChatProvider::send(msg);}
294
295
296=== modified file 'src/network/netclient.cc'
297--- src/network/netclient.cc 2013-04-22 20:15:00 +0000
298+++ src/network/netclient.cc 2013-07-16 17:39:34 +0000
299@@ -628,6 +628,15 @@
300 s.send(d->sock);
301 }
302
303+void NetClient::send_local(const std::string& msg)
304+{
305+ ChatMessage c;
306+ c.msg = msg;
307+ c.time = time(0);
308+ d->chatmessages.push_back(c);
309+ ChatProvider::send(c);
310+}
311+
312 const std::vector<ChatMessage> & NetClient::getMessages() const
313 {
314 return d->chatmessages;
315
316=== modified file 'src/network/netclient.h'
317--- src/network/netclient.h 2013-02-10 19:36:24 +0000
318+++ src/network/netclient.h 2013-07-16 17:39:34 +0000
319@@ -92,6 +92,7 @@
320
321 // ChatProvider interface
322 void send(const std::string & msg);
323+ void send_local(const std::string & msg);
324 const std::vector<ChatMessage> & getMessages() const;
325
326 private:
327
328=== modified file 'src/network/nethost.cc'
329--- src/network/nethost.cc 2013-07-15 05:18:12 +0000
330+++ src/network/nethost.cc 2013-07-16 17:39:34 +0000
331@@ -498,6 +498,13 @@
332 h->send(c);
333 }
334
335+ void send_local(const std::string & msg) {
336+ ChatMessage c;
337+ c.time = time(0);
338+ c.msg = msg;
339+ ChatProvider::send(c);
340+ }
341+
342 const std::vector<ChatMessage> & getMessages() const {
343 return messages;
344 }
345
346=== modified file 'src/save_handler.cc'
347--- src/save_handler.cc 2013-07-14 11:48:13 +0000
348+++ src/save_handler.cc 2013-07-16 17:39:34 +0000
349@@ -25,6 +25,8 @@
350 #include "io/filesystem/filesystem.h"
351 #include "game_io/game_saver.h"
352 #include "profile/profile.h"
353+#include "wui/interactive_player.h"
354+#include "chat.h"
355
356 #include "log.h"
357
358@@ -51,7 +53,10 @@
359 if (elapsed < autosaveInterval)
360 return;
361
362- log("Autosave: interval elapsed (%d s), saving\n", elapsed);
363+ // TODO: defer saving to next tick so that this message is shown
364+ // before the actual save, or put the saving logic in another thread
365+ game.get_ipl()->get_chat_provider()->send_local
366+ (_("Saving game..."));
367
368 // save the game
369 std::string complete_filename =
370@@ -70,6 +75,8 @@
371 static std::string error;
372 if (!save_game(game, complete_filename, &error)) {
373 log("Autosave: ERROR! - %s\n", error.c_str());
374+ game.get_ipl()->get_chat_provider()->send_local
375+ (_("Saving failed!"));
376
377 // if backup file was created, move it back
378 if (backup_filename.length() > 0) {
379@@ -88,6 +95,8 @@
380 }
381
382 log("Autosave: save took %d ms\n", m_last_saved_time - realtime);
383+ game.get_ipl()->get_chat_provider()->send_local
384+ (_("Game saved"));
385 }
386
387 /**
388@@ -98,7 +107,6 @@
389 return;
390
391 m_last_saved_time = currenttime;
392- log("Autosave: initialized\n");
393 m_initialized = true;
394 }
395
396
397=== modified file 'src/timestring.cc'
398--- src/timestring.cc 2013-03-21 10:45:51 +0000
399+++ src/timestring.cc 2013-07-16 17:39:34 +0000
400@@ -75,3 +75,18 @@
401 }
402 return timestring_buffer;
403 }
404+
405+char gamestringbuffer[] = "000:00:00";
406+char * gametimestring(uint32_t gametime)
407+{
408+ uint32_t time = gametime / 1000;
409+ gamestringbuffer[8] = '0' + time % 10;
410+ gamestringbuffer[7] = '0' + (time /= 10) % 6;
411+ gamestringbuffer[5] = '0' + (time /= 6) % 10;
412+ gamestringbuffer[4] = '0' + (time /= 10) % 6;
413+ gamestringbuffer[2] = '0' + (time /= 6) % 10;
414+ gamestringbuffer[1] = '0' + (time /= 10) % 10;
415+ gamestringbuffer[0] = '0' + (time /= 10);
416+ return gamestringbuffer;
417+}
418+
419
420=== modified file 'src/timestring.h'
421--- src/timestring.h 2012-02-15 21:25:34 +0000
422+++ src/timestring.h 2013-07-16 17:39:34 +0000
423@@ -21,3 +21,8 @@
424 /// seconds since the Epoch). The return value points to a statically allocated
425 /// string which might be overwritten by subsequent calls.
426 char * timestring();
427+
428+/// Get a string representation of the game time
429+/// as hhh:mm:ss. If Time represents more than
430+/// 999 hours, it wraps around
431+char * gametimestring(uint32_t gametime);
432
433=== modified file 'src/ui_basic/progressbar.cc'
434--- src/ui_basic/progressbar.cc 2012-02-15 21:25:34 +0000
435+++ src/ui_basic/progressbar.cc 2013-07-16 17:39:34 +0000
436@@ -21,10 +21,12 @@
437
438 #include "constants.h"
439 #include "graphic/font.h"
440-#include "graphic/font_handler.h"
441+#include "graphic/font_handler1.h"
442+#include "text_layout.h"
443 #include "graphic/rendertarget.h"
444
445 #include <cstdio>
446+#include <boost/format.hpp>
447
448
449 namespace UI {
450@@ -103,16 +105,11 @@
451 }
452
453 // Print the state in percent
454- char buffer[30];
455-
456- snprintf
457- (buffer, sizeof(buffer), "%u%%", static_cast<uint32_t>(fraction * 100));
458-
459- UI::g_fh->draw_text
460- (dst, UI::TextStyle::ui_small(),
461- Point(get_w() / 2, get_h() / 2),
462- buffer,
463- Align_Center);
464+ // TODO use UI_FNT_COLOR_BRIGHT when merged
465+ uint32_t percent = static_cast<uint32_t>(fraction * 100);
466+ const std::string progress_text =
467+ (boost::format("<font color=%1$s>%2$i%%</font>") % "ffffff" % percent).str();
468+ const Point pos(get_w() / 2, get_h() / 2);
469+ dst.blit(pos, UI::g_fh1->render(as_uifont(progress_text)), CM_Normal, Align_Center);
470 }
471-
472 }
473
474=== modified file 'src/ui_basic/table.cc'
475--- src/ui_basic/table.cc 2013-07-13 14:25:41 +0000
476+++ src/ui_basic/table.cc 2013-07-16 17:39:34 +0000
477@@ -23,11 +23,13 @@
478 #include "graphic/font_handler.h"
479 #include "graphic/graphic.h"
480 #include "graphic/rendertarget.h"
481+#include "graphic/font_handler1.h"
482
483 #include "button.h"
484 #include "mouse_constants.h"
485 #include "scrollbar.h"
486 #include "wlapplication.h"
487+#include "text_layout.h"
488
489 #include "container_iterate.h"
490 #include <boost/bind.hpp>
491@@ -273,21 +275,13 @@
492 const std::string & entry_string = er.get_string (i);
493 uint32_t picw = 0;
494 uint32_t pich = 0;
495- uint32_t stringw = 0;
496- uint32_t stringh = g_fh->get_fontheight(m_fontname, m_fontsize);
497+
498 if (entry_picture) {
499 picw = entry_picture->width();
500 pich = entry_picture->height();
501 }
502- Point point =
503- Point(curx, y)
504- +
505- Point
506- (alignment & Align_Right ? curw - (picw + stringw) - 1 :
507- alignment & Align_HCenter ? (curw - (picw + stringw)) / 2 :
508- 1,
509- 0);
510- if (entry_picture)
511+ Point point(curx, y);
512+ if (entry_picture) {
513 dst.blit
514 (point +
515 Point
516@@ -296,18 +290,13 @@
517 static_cast<int32_t>(pich))
518 / 2),
519 entry_picture);
520+ point.x += picw;
521+ }
522
523- UI::g_fh->draw_text
524- (dst,
525- TextStyle::makebold(Font::get(m_fontname, m_fontsize), er.use_clr ? er.clr : UI_FONT_CLR_FG),
526- point +
527- Point
528- (picw,
529- (static_cast<int32_t>(lineheight) -
530- static_cast<int32_t>(stringh))
531- / 2),
532- entry_string,
533- alignment);
534+ const Image* entry_text_im = UI::g_fh1->render(as_uifont(entry_string, m_fontsize));
535+ // Crop to column width
536+ UI::correct_for_align(alignment, entry_text_im->width(), entry_text_im->height(), &point);
537+ dst.blitrect(point, entry_text_im, Rect(0, 0, curw - picw, lineheight));
538
539 curx += curw;
540 }
541
542=== modified file 'src/ui_fsmenu/loadgame.cc'
543--- src/ui_fsmenu/loadgame.cc 2013-07-15 05:18:12 +0000
544+++ src/ui_fsmenu/loadgame.cc 2013-07-16 17:39:34 +0000
545@@ -29,6 +29,7 @@
546 #include "log.h"
547 #include "logic/game.h"
548 #include "ui_basic/messagebox.h"
549+#include "timestring.h"
550
551 #include <cstdio>
552
553@@ -203,15 +204,9 @@
554 m_tamapname.set_text(_(gpdp.get_mapname()));
555 }
556
557- char buf[200];
558+ char buf[20];
559 uint32_t gametime = gpdp.get_gametime();
560-
561- int32_t hours = gametime / 3600000;
562- gametime -= hours * 3600000;
563- int32_t minutes = gametime / 60000;
564-
565- sprintf(buf, "%02i:%02i", hours, minutes);
566- m_tagametime.set_text(buf);
567+ m_tagametime.set_text(gametimestring(gametime));
568
569 sprintf(buf, "%i", gpdp.get_player_nr());
570 m_ta_players.set_text(buf);
571
572=== modified file 'src/ui_fsmenu/loadreplay.cc'
573--- src/ui_fsmenu/loadreplay.cc 2013-07-14 16:11:41 +0000
574+++ src/ui_fsmenu/loadreplay.cc 2013-07-16 17:39:34 +0000
575@@ -28,6 +28,7 @@
576 #include "logic/game.h"
577 #include "logic/replay.h"
578 #include "ui_basic/messagebox.h"
579+#include "timestring.h"
580
581 Fullscreen_Menu_LoadReplay::Fullscreen_Menu_LoadReplay() :
582 Fullscreen_Menu_Base("choosemapmenu.jpg"),
583@@ -186,15 +187,9 @@
584 m_delete.set_enabled(true);
585 m_tamapname.set_text(gpdp.get_mapname());
586
587- char buf[200];
588+ char buf[20];
589 uint32_t gametime = gpdp.get_gametime();
590-
591- int32_t hours = gametime / 3600000;
592- gametime -= hours * 3600000;
593- int32_t minutes = gametime / 60000;
594-
595- sprintf(buf, "%02i:%02i", hours, minutes);
596- m_tagametime.set_text(buf);
597+ m_tagametime.set_text(gametimestring(gametime));
598
599 sprintf(buf, "%i", gpdp.get_player_nr());
600 m_ta_players.set_text(buf);
601
602=== modified file 'src/ui_fsmenu/mapselect.cc'
603--- src/ui_fsmenu/mapselect.cc 2013-06-15 14:35:17 +0000
604+++ src/ui_fsmenu/mapselect.cc 2013-07-16 17:39:34 +0000
605@@ -172,11 +172,11 @@
606 vbox->set_size(get_w(), 25);
607 vbox = new UI::Box(this, m_table.get_x(), m_table.get_y() - 60, UI::Box::Horizontal, m_table.get_w());
608 _add_tag_checkbox(vbox, "1v1", _("1v1"));
609- _add_tag_checkbox(vbox, "2teams", _("2 Player Teams"));
610- _add_tag_checkbox(vbox, "3teams", _("3 Player Teams"));
611+ _add_tag_checkbox(vbox, "2teams", _("Teams of 2"));
612+ _add_tag_checkbox(vbox, "3teams", _("Teams of 3"));
613 vbox->set_size(get_w(), 25);
614 vbox = new UI::Box(this, m_table.get_x(), m_table.get_y() - 30, UI::Box::Horizontal, m_table.get_w());
615- _add_tag_checkbox(vbox, "4teams", _("4 Player Teams"));
616+ _add_tag_checkbox(vbox, "4teams", _("Teams of 4"));
617 _add_tag_checkbox(vbox, "ffa", _("Free for all"));
618 _add_tag_checkbox(vbox, "unbalanced", _("Unbalanced"));
619 vbox->set_size(get_w(), 25);
620
621=== modified file 'src/wlapplication.cc'
622--- src/wlapplication.cc 2013-07-15 05:18:12 +0000
623+++ src/wlapplication.cc 2013-07-16 17:39:34 +0000
624@@ -2036,9 +2036,14 @@
625 }
626 } else { // normal singleplayer
627 uint8_t const pn = sp.settings().playernum + 1;
628- boost::scoped_ptr<GameController> ctrl
629- (GameController::createSinglePlayer(game, true, pn));
630 try {
631+ // Game controller needs the ibase pointer to init
632+ // the chat
633+ game.set_ibase
634+ (new Interactive_Player
635+ (game, g_options.pull_section("global"), pn, false, false));
636+ boost::scoped_ptr<GameController> ctrl
637+ (GameController::createSinglePlayer(game, true, pn));
638 UI::ProgressWindow loaderUI;
639 std::vector<std::string> tipstext;
640 tipstext.push_back("general_game");
641@@ -2052,9 +2057,6 @@
642 loaderUI.step(_("Preparing game"));
643
644 game.set_game_controller(ctrl.get());
645- game.set_ibase
646- (new Interactive_Player
647- (game, g_options.pull_section("global"), pn, false, false));
648 game.init_newgame(&loaderUI, sp.settings());
649 game.run(&loaderUI, Widelands::Game::NewNonScenario);
650 } catch (const std::exception & e) {
651
652=== modified file 'src/wui/building_ui.cc'
653--- src/wui/building_ui.cc 2013-07-09 05:53:39 +0000
654+++ src/wui/building_ui.cc 2013-07-16 17:39:34 +0000
655@@ -17,6 +17,8 @@
656 *
657 */
658
659+#include <boost/foreach.hpp>
660+#include <boost/lexical_cast.hpp>
661 #include "buildingwindow.h"
662 #include "logic/building.h"
663 #include "ui_basic/window.h"
664@@ -30,14 +32,17 @@
665 */
666 void Building::show_options(Interactive_GameBase & igbase, bool avoid_fastclick)
667 {
668+ // Reset tooltip before opening the window
669+ igbase.set_tooltip("");
670 if (m_optionswindow) {
671 if (m_optionswindow->is_minimal())
672 m_optionswindow->restore();
673 m_optionswindow->move_to_top();
674 } else {
675 create_options_window(igbase, m_optionswindow);
676- if (upcast(Building_Window, bw, m_optionswindow))
677+ if (upcast(Building_Window, bw, m_optionswindow)) {
678 bw->set_avoid_fastclick(avoid_fastclick);
679+ }
680 // Run a first think here so that certain things like caps buttons
681 // get properly initialized
682 m_optionswindow->think();
683@@ -49,6 +54,8 @@
684 */
685 void Building::hide_options()
686 {
687+ BOOST_FOREACH(boost::signals::connection& c, options_window_connections)
688+ c.disconnect();
689 delete m_optionswindow;
690 m_optionswindow = NULL;
691 }
692
693=== modified file 'src/wui/buildingwindow.cc'
694--- src/wui/buildingwindow.cc 2013-07-13 15:58:52 +0000
695+++ src/wui/buildingwindow.cc 2013-07-16 17:39:34 +0000
696@@ -79,13 +79,6 @@
697 set_center_panel(vbox);
698 set_think(true);
699
700- char filename[] = "pics/workarea0cumulative.png";
701- compile_assert(NUMBER_OF_WORKAREA_PICS <= 9);
702- for (Workarea_Info::size_type i = 0; i < NUMBER_OF_WORKAREA_PICS; ++i) {
703- ++filename[13];
704- workarea_cumulative_pic[i] = g_gr->images().get(filename);
705- }
706-
707 show_workarea();
708
709 set_fastclick_panel(this);
710@@ -327,7 +320,7 @@
711 (capsbuttons, "workarea",
712 0, 0, 34, 34,
713 g_gr->images().get("pics/but4.png"),
714- g_gr->images().get("pics/workarea3cumulative.png"),
715+ g_gr->images().get("pics/workarea123.png"),
716 _("Hide workarea"));
717 m_toggle_workarea->sigclicked.connect
718 (boost::bind(&Building_Window::toggle_workarea, boost::ref(*this)));
719@@ -512,41 +505,11 @@
720 */
721 void Building_Window::show_workarea()
722 {
723- if (m_workarea_job_id)
724+ if (m_workarea_job_id) {
725 return; // already shown, nothing to be done
726-
727+ }
728 const Workarea_Info & workarea_info = m_building.descr().m_workarea_info;
729- if (workarea_info.size() == 0)
730- return; // building has no workarea
731-
732- Widelands::Map & map =
733- ref_cast<const Interactive_GameBase, UI::Panel>(*get_parent()).egbase()
734- .map();
735- Overlay_Manager & overlay_manager = map.overlay_manager();
736- m_workarea_job_id = overlay_manager.get_a_job_id();
737-
738- Widelands::HollowArea<> hollow_area
739- (Widelands::Area<>(m_building.get_position(), 0), 0);
740- Workarea_Info::const_iterator it = workarea_info.begin();
741- for
742- (Workarea_Info::size_type i =
743- std::min(workarea_info.size(), NUMBER_OF_WORKAREA_PICS);
744- i;
745- ++it)
746- {
747- --i;
748- hollow_area.radius = it->first;
749- Widelands::MapHollowRegion<> mr(map, hollow_area);
750- do
751- overlay_manager.register_overlay
752- (mr.location(),
753- workarea_cumulative_pic[i],
754- 0,
755- Point::invalid(),
756- m_workarea_job_id);
757- while (mr.advance(map));
758- hollow_area.hole_radius = hollow_area.radius;
759- }
760+ m_workarea_job_id = igbase().show_work_area(workarea_info, m_building.get_position());
761
762 configure_workarea_button();
763 }
764@@ -557,11 +520,7 @@
765 void Building_Window::hide_workarea()
766 {
767 if (m_workarea_job_id) {
768- Widelands::Map & map =
769- ref_cast<const Interactive_GameBase, UI::Panel>(*get_parent()).egbase()
770- .map();
771- Overlay_Manager & overlay_manager = map.overlay_manager();
772- overlay_manager.remove_overlay(m_workarea_job_id);
773+ igbase().hide_work_area(m_workarea_job_id);
774 m_workarea_job_id = Overlay_Manager::Job_Id::Null();
775
776 configure_workarea_button();
777
778=== modified file 'src/wui/buildingwindow.h'
779--- src/wui/buildingwindow.h 2013-07-08 03:35:09 +0000
780+++ src/wui/buildingwindow.h 2013-07-16 17:39:34 +0000
781@@ -94,7 +94,6 @@
782 bool m_caps_setup;
783
784 Overlay_Manager::Job_Id m_workarea_job_id;
785- const Image* workarea_cumulative_pic[NUMBER_OF_WORKAREA_PICS];
786 bool m_avoid_fastclick;
787 };
788
789
790=== modified file 'src/wui/fieldaction.cc'
791--- src/wui/fieldaction.cc 2013-02-09 23:36:30 +0000
792+++ src/wui/fieldaction.cc 2013-07-16 17:39:34 +0000
793@@ -231,7 +231,6 @@
794 bool m_fastclick; // if true, put the mouse over first button in first tab
795 uint32_t m_best_tab;
796 Overlay_Manager::Job_Id m_workarea_preview_job_id;
797- const Image* workarea_cumulative_pic[NUMBER_OF_WORKAREA_PICS];
798
799 /// Variables to use with attack dialog.
800 AttackBox * m_attack_box;
801@@ -297,13 +296,6 @@
802
803
804 set_center_panel(&m_tabpanel);
805-
806- char filename[] = "pics/workarea0cumulative.png";
807- compile_assert(NUMBER_OF_WORKAREA_PICS <= 9);
808- for (Workarea_Info::size_type i = 0; i < NUMBER_OF_WORKAREA_PICS; ++i) {
809- ++filename[13];
810- workarea_cumulative_pic[i] = g_gr->images().get(filename);
811- }
812 }
813
814
815@@ -856,44 +848,10 @@
816 (const Widelands::Building_Index::value_t idx)
817 {
818 if (ibase().m_show_workarea_preview and not m_workarea_preview_job_id) {
819- m_workarea_preview_job_id = m_overlay_manager.get_a_job_id();
820- Widelands::HollowArea<> hollow_area(Widelands::Area<>(m_node, 0), 0);
821 const Workarea_Info & workarea_info =
822 m_plr->tribe().get_building_descr(Widelands::Building_Index(idx))
823 ->m_workarea_info;
824- Workarea_Info::const_iterator it = workarea_info.begin();
825- for
826- (Workarea_Info::size_type i =
827- std::min(workarea_info.size(), NUMBER_OF_WORKAREA_PICS);
828- i;
829- ++it)
830- {
831- --i;
832- hollow_area.radius = it->first;
833- assert(hollow_area.radius);
834- assert(hollow_area.hole_radius < hollow_area.radius);
835- Widelands::MapHollowRegion<> mr(*m_map, hollow_area);
836- do
837- m_overlay_manager.register_overlay
838- (mr.location(),
839- workarea_cumulative_pic[i],
840- 0,
841- Point::invalid(),
842- m_workarea_preview_job_id);
843- while (mr.advance(*m_map));
844- hollow_area.hole_radius = hollow_area.radius;
845- }
846-
847-#if 0
848- // This is debug output.
849- // Improvement suggestion: add to sign explanation window instead.
850- container_iterate_const(Workarea_Info, workarea_info, i) {
851- log("Radius: %i\n", i.current->first);
852- container_iterate_const(std::set<std::string>, i.current->second, j)
853- log(" %s\n", j.current->c_str());
854- }
855-#endif
856-
857+ m_workarea_preview_job_id = ibase().show_work_area(workarea_info, m_node);
858 }
859 }
860
861
862=== modified file 'src/wui/game_main_menu_save_game.cc'
863--- src/wui/game_main_menu_save_game.cc 2013-07-15 11:01:59 +0000
864+++ src/wui/game_main_menu_save_game.cc 2013-07-16 17:39:34 +0000
865@@ -28,10 +28,13 @@
866 #include "game_io/game_saver.h"
867 #include "i18n.h"
868 #include "interactive_gamebase.h"
869+#include "gamecontroller.h"
870 #include "io/filesystem/filesystem.h"
871 #include "io/filesystem/layered_filesystem.h"
872 #include "logic/game.h"
873 #include "profile/profile.h"
874+#include "interactive_player.h"
875+#include "timestring.h"
876
877 using boost::format;
878
879@@ -125,6 +128,10 @@
880 }
881
882 m_editbox->focus();
883+ if (!parent.game().get_ipl()->is_multiplayer()) {
884+ // Pause the game
885+ parent.game().gameController()->setPaused(true);
886+ }
887 }
888
889
890@@ -144,20 +151,11 @@
891 m_button_ok->set_enabled(true);
892
893 m_name.set_text(gpdp.get_mapname());
894+
895+ uint32_t gametime = gpdp.get_gametime();
896+ m_gametime.set_text(gametimestring(gametime));
897+
898 char buf[200];
899- uint32_t gametime = gpdp.get_gametime();
900-#define SPLIT_GAMETIME(unit, factor) \
901- uint32_t const unit = gametime / factor; gametime %= factor;
902- SPLIT_GAMETIME(days, 86400000);
903- SPLIT_GAMETIME(hours, 3600000);
904- SPLIT_GAMETIME(minutes, 60000);
905- SPLIT_GAMETIME(seconds, 1000);
906- sprintf
907- (buf,
908- _("%02ud%02uh%02u'%02u\"%03u"),
909- days, hours, minutes, seconds, gametime);
910- m_gametime.set_text(buf);
911-
912 sprintf
913 (buf, "%i %s", gpdp.get_player_nr(),
914 ngettext(_("player"), _("players"), gpdp.get_player_nr()));
915@@ -293,6 +291,15 @@
916 }
917 }
918
919+void Game_Main_Menu_Save_Game::die()
920+{
921+ UI::UniqueWindow::die();
922+ if (!igbase().game().get_ipl()->is_multiplayer()) {
923+ igbase().game().gameController()->setPaused(false);
924+ }
925+}
926+
927+
928
929 struct DeletionMessageBox : public UI::WLMessageBox {
930 DeletionMessageBox
931
932=== modified file 'src/wui/game_main_menu_save_game.h'
933--- src/wui/game_main_menu_save_game.h 2013-07-13 15:17:51 +0000
934+++ src/wui/game_main_menu_save_game.h 2013-07-16 17:39:34 +0000
935@@ -43,7 +43,7 @@
936 void select_by_name(std::string name);
937 private:
938 Interactive_GameBase & igbase();
939- void die() {UI::UniqueWindow::die();}
940+ void die();
941 void selected (uint32_t);
942 void double_clicked(uint32_t);
943 void edit_box_changed();
944
945=== modified file 'src/wui/game_message_menu.cc'
946--- src/wui/game_message_menu.cc 2013-07-12 15:11:32 +0000
947+++ src/wui/game_message_menu.cc 2013-07-16 17:39:34 +0000
948@@ -28,6 +28,7 @@
949 #include "logic/playercommand.h"
950
951 #include "container_iterate.h"
952+#include "timestring.h"
953
954 using Widelands::Message;
955 using Widelands::Message_Id;
956@@ -109,6 +110,8 @@
957
958 list->set_column_compare
959 (ColStatus, boost::bind(&GameMessageMenu::status_compare, this, _1, _2));
960+ list->set_sort_column(ColTimeSent);
961+ list->set_sort_descending(true);
962
963 set_can_focus(true);
964 focus();
965@@ -200,19 +203,8 @@
966 g_gr->images().get(status_picture_filename[message.status()]));
967 er.set_string(ColTitle, message.title());
968
969- uint32_t time = message.sent();
970- char timestring[] = "000:00:00.000";
971- timestring[12] += time % 10;
972- timestring[11] += (time /= 10) % 10;
973- timestring[10] += (time /= 10) % 10;
974- timestring [8] += (time /= 10) % 10;
975- timestring [7] += (time /= 10) % 6;
976- timestring [5] += (time /= 6) % 10;
977- timestring [4] += (time /= 10) % 6;
978- timestring [2] += (time /= 6) % 10;
979- timestring [1] += (time /= 10) % 10;
980- timestring [0] += time /= 10;
981- er.set_string(ColTimeSent, time < 10 ? timestring : "-------------");
982+ const uint32_t time = message.sent();
983+ er.set_string(ColTimeSent, gametimestring(time));
984 }
985
986 /*
987
988=== modified file 'src/wui/interactive_base.cc'
989--- src/wui/interactive_base.cc 2013-06-15 13:38:19 +0000
990+++ src/wui/interactive_base.cc 2013-07-16 17:39:34 +0000
991@@ -36,6 +36,7 @@
992 #include "logic/maptriangleregion.h"
993 #include "logic/player.h"
994 #include "logic/productionsite.h"
995+#include "logic/maphollowregion.h"
996 #include "mapviewpixelconstants.h"
997 #include "mapviewpixelfunctions.h"
998 #include "minimap.h"
999@@ -119,6 +120,15 @@
1000 // funny results.
1001 m_sel.pic = g_gr->images().get("pics/fsel.png");
1002
1003+ // Load workarea images.
1004+ // Start at idx 0 for 2 enhancements, idx 3 for 1, idx 5 if none
1005+ workarea_pics[0] = g_gr->images().get("pics/workarea123.png");
1006+ workarea_pics[1] = g_gr->images().get("pics/workarea23.png");
1007+ workarea_pics[2] = g_gr->images().get("pics/workarea3.png");
1008+ workarea_pics[3] = g_gr->images().get("pics/workarea12.png");
1009+ workarea_pics[4] = g_gr->images().get("pics/workarea2.png");
1010+ workarea_pics[5] = g_gr->images().get("pics/workarea1.png");
1011+
1012 m_label_speed.set_visible(false);
1013 m_label_speed_shadow.set_visible(false);
1014
1015@@ -229,6 +239,60 @@
1016 egbase().map().overlay_manager().show_buildhelp(t);
1017 }
1018
1019+// Show the given workareas at the given coords and returns the overlay job id associated
1020+Overlay_Manager::Job_Id Interactive_Base::show_work_area
1021+ (const Workarea_Info & workarea_info, Widelands::Coords coords)
1022+{
1023+ uint8_t workareas_nrs = workarea_info.size();
1024+ Workarea_Info::size_type wa_index;
1025+ switch (workareas_nrs) {
1026+ case 0: return Overlay_Manager::Job_Id::Null(); break; // no workarea
1027+ case 1: wa_index = 5; break;
1028+ case 2: wa_index = 3; break;
1029+ case 3: wa_index = 0; break;
1030+ default: assert(false); break;
1031+ }
1032+ Widelands::Map & map = m_egbase.map();
1033+ Overlay_Manager & overlay_manager = map.overlay_manager();
1034+ Overlay_Manager::Job_Id job_id = overlay_manager.get_a_job_id();
1035+
1036+ Widelands::HollowArea<> hollow_area(Widelands::Area<>(coords, 0), 0);
1037+
1038+ // Iterate through the work areas, from building to its enhancement
1039+ Workarea_Info::const_iterator it = workarea_info.begin();
1040+ for (; it != workarea_info.end(); ++it) {
1041+ assert(wa_index < NUMBER_OF_WORKAREA_PICS);
1042+ hollow_area.radius = it->first;
1043+ Widelands::MapHollowRegion<> mr(map, hollow_area);
1044+ do
1045+ overlay_manager.register_overlay
1046+ (mr.location(),
1047+ workarea_pics[wa_index],
1048+ 0,
1049+ Point::invalid(),
1050+ job_id);
1051+ while (mr.advance(map));
1052+ wa_index++;
1053+ hollow_area.hole_radius = hollow_area.radius;
1054+ }
1055+ return job_id;
1056+#if 0
1057+ // This is debug output.
1058+ // Improvement suggestion: add to sign explanation window instead.
1059+ container_iterate_const(Workarea_Info, workarea_info, i) {
1060+ log("Radius: %i\n", i.current->first);
1061+ container_iterate_const(std::set<std::string>, i.current->second, j)
1062+ log(" %s\n", j.current->c_str());
1063+ }
1064+#endif
1065+}
1066+
1067+void Interactive_Base::hide_work_area(Overlay_Manager::Job_Id job_id) {
1068+ Widelands::Map & map = m_egbase.map();
1069+ Overlay_Manager & overlay_manager = map.overlay_manager();
1070+ overlay_manager.remove_overlay(job_id);
1071+}
1072+
1073
1074 /**
1075 * Called by \ref Game::postload at the end of the game loading
1076
1077=== modified file 'src/wui/interactive_base.h'
1078--- src/wui/interactive_base.h 2013-02-10 19:36:24 +0000
1079+++ src/wui/interactive_base.h 2013-07-16 17:39:34 +0000
1080@@ -60,6 +60,8 @@
1081 virtual void reference_player_tribe(Widelands::Player_Number, const void * const) {}
1082
1083 bool m_show_workarea_preview;
1084+ Overlay_Manager::Job_Id show_work_area(const Workarea_Info & workarea_info, Widelands::Coords coords);
1085+ void hide_work_area(Overlay_Manager::Job_Id job_id);
1086
1087 // point of view for drawing
1088 virtual Widelands::Player * get_player() const throw () = 0;
1089@@ -151,6 +153,7 @@
1090 Overlay_Manager::Job_Id m_road_buildhelp_overlay_jobid;
1091 Widelands::CoordPath * m_buildroad; // path for the new road
1092 Widelands::Player_Number m_road_build_player;
1093+ const Image* workarea_pics[NUMBER_OF_WORKAREA_PICS];
1094
1095 protected:
1096 void toggle_minimap();
1097
1098=== modified file 'src/wui/interactive_player.cc'
1099--- src/wui/interactive_player.cc 2013-02-21 19:02:21 +0000
1100+++ src/wui/interactive_player.cc 2013-07-16 17:39:34 +0000
1101@@ -85,7 +85,8 @@
1102 :
1103 Interactive_GameBase (_game, global_s),
1104 m_auto_roadbuild_mode(global_s.get_bool("auto_roadbuild_mode", true)),
1105-m_flag_to_connect(Widelands::Coords::Null()),
1106+ m_flag_to_connect(Widelands::Coords::Null()),
1107+ m_multiplayer(multiplayer),
1108
1109 // Chat is different, as m_chatProvider needs to be checked when toggling
1110 // Buildhelp is different as it does not toggle a UniqueWindow
1111@@ -152,16 +153,16 @@
1112 m_toolbar.add(&m_toggle_statistics_menu, UI::Box::AlignLeft);
1113 m_toolbar.add(&m_toggle_minimap, UI::Box::AlignLeft);
1114 m_toolbar.add(&m_toggle_buildhelp, UI::Box::AlignLeft);
1115+ // Limit chat width to half the screen, to limit the damage lamers can do
1116+ // by flooding chat messages
1117+ m_chatOverlay =
1118+ new ChatOverlay(this, 10, 25, get_w() / 2, get_h() - 25);
1119 if (multiplayer) {
1120 m_toolbar.add(&m_toggle_chat, UI::Box::AlignLeft);
1121- // Limit chat width to half the screen, to limit the damage lamers can do
1122- // by flooding chat messages
1123- m_chatOverlay =
1124- new ChatOverlay(this, 10, 25, get_w() / 2, get_h() - 25);
1125 m_toggle_chat.set_visible(false);
1126 m_toggle_chat.set_enabled(false);
1127- } else
1128- m_toggle_chat.set_visible(false);
1129+ }
1130+
1131 m_toolbar.add(&m_toggle_help, UI::Box::AlignLeft);
1132 if (not scenario)
1133 m_toggle_objectives.set_visible(false);
1134@@ -283,8 +284,10 @@
1135 m_flag_to_connect = Widelands::Coords::Null();
1136 }
1137 }
1138- m_toggle_chat.set_visible(m_chatenabled);
1139- m_toggle_chat.set_enabled(m_chatenabled);
1140+ if (m_multiplayer) {
1141+ m_toggle_chat.set_visible(m_chatenabled);
1142+ m_toggle_chat.set_enabled(m_chatenabled);
1143+ }
1144 {
1145 char buffer[128];
1146 char const * msg_icon = "pics/menu_toggle_oldmessage_menu.png";
1147@@ -452,7 +455,7 @@
1148
1149 case SDLK_KP_ENTER:
1150 case SDLK_RETURN:
1151- if (!m_chatProvider | !m_chatenabled)
1152+ if (!m_chatProvider | !m_chatenabled || !m_multiplayer)
1153 break;
1154
1155 if (!m_chat.window)
1156
1157=== modified file 'src/wui/interactive_player.h'
1158--- src/wui/interactive_player.h 2013-02-10 19:36:24 +0000
1159+++ src/wui/interactive_player.h 2013-07-16 17:39:34 +0000
1160@@ -88,12 +88,15 @@
1161
1162 void popup_message(Widelands::Message_Id, const Widelands::Message &);
1163
1164+ bool is_multiplayer() {return m_multiplayer;}
1165+
1166 private:
1167 void cmdSwitchPlayer(const std::vector<std::string> & args);
1168
1169 Widelands::Player_Number m_player_number;
1170 bool m_auto_roadbuild_mode;
1171 Widelands::Coords m_flag_to_connect;
1172+ bool m_multiplayer;
1173
1174 UI::Button m_toggle_chat;
1175 UI::Button m_toggle_options_menu;
1176
1177=== modified file 'src/wui/productionsitewindow.cc'
1178--- src/wui/productionsitewindow.cc 2013-02-10 19:36:24 +0000
1179+++ src/wui/productionsitewindow.cc 2013-07-16 17:39:34 +0000
1180@@ -105,13 +105,41 @@
1181 worker_box,
1182 productionsite().descr().nr_working_positions() > 1 ?
1183 _("Workers") : _("Worker"));
1184+ update_worker_table();
1185 }
1186 }
1187
1188 void ProductionSite_Window::think()
1189 {
1190 Building_Window::think();
1191-
1192+ // If we have pending requests, update table as the worker might be coming
1193+ for
1194+ (unsigned int i = 0;
1195+ i < productionsite().descr().nr_working_positions(); ++i)
1196+ {
1197+ if (productionsite().working_positions()[i].worker_request) {
1198+ update_worker_table();
1199+ break;
1200+ }
1201+ }
1202+}
1203+
1204+/*
1205+===============
1206+Create the production site information window.
1207+===============
1208+*/
1209+void ProductionSite::create_options_window
1210+ (Interactive_GameBase & parent, UI::Window * & registry)
1211+{
1212+ ProductionSite_Window* win = new ProductionSite_Window(parent, *this, registry);
1213+ options_window_connections.push_back
1214+ (workers_changed.connect(boost::bind
1215+ (&ProductionSite_Window::update_worker_table, boost::ref(*win))));
1216+}
1217+
1218+void ProductionSite_Window::update_worker_table()
1219+{
1220 if (m_worker_table) {
1221 assert
1222 (productionsite().descr().nr_working_positions() ==
1223@@ -155,7 +183,7 @@
1224 er.set_string(1, "---");
1225 er.set_string(2, "---");
1226 }
1227- } else {
1228+ } else if (request) {
1229 const Widelands::Worker_Descr * desc =
1230 productionsite().tribe().get_worker_descr(request->get_index());
1231 er.set_picture
1232@@ -164,20 +192,13 @@
1233
1234 er.set_string(1, "");
1235 er.set_string(2, "");
1236+ } else {
1237+ // Occurs during cleanup
1238+ return;
1239 }
1240 }
1241 }
1242-}
1243-
1244-/*
1245-===============
1246-Create the production site information window.
1247-===============
1248-*/
1249-void ProductionSite::create_options_window
1250- (Interactive_GameBase & parent, UI::Window * & registry)
1251-{
1252- new ProductionSite_Window(parent, *this, registry);
1253+ m_worker_table->update();
1254 }
1255
1256 void ProductionSite_Window::evict_worker() {
1257
1258=== modified file 'src/wui/productionsitewindow.h'
1259--- src/wui/productionsitewindow.h 2013-02-02 14:42:48 +0000
1260+++ src/wui/productionsitewindow.h 2013-07-16 17:39:34 +0000
1261@@ -33,7 +33,7 @@
1262 Widelands::ProductionSite & productionsite() {
1263 return ref_cast<Widelands::ProductionSite, Widelands::Building>(building());
1264 }
1265-
1266+ void update_worker_table();
1267 protected:
1268 virtual void think();
1269 void evict_worker();