1 /**********************************************************************
2  Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold
3    This program is free software; you can redistribute it and/or modify
4    it under the terms of the GNU General Public License as published by
5    the Free Software Foundation; either version 2, or (at your option)
6    any later version.
7 
8    This program is distributed in the hope that it will be useful,
9    but WITHOUT ANY WARRANTY; without even the implied warranty of
10    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11    GNU General Public License for more details.
12 ***********************************************************************/
13 
14 #ifdef HAVE_CONFIG_H
15 #include <fc_config.h>
16 #endif
17 
18 /* SDL */
19 #include <SDL/SDL.h>
20 
21 /* utility */
22 #include "astring.h"
23 #include "fcintl.h"
24 
25 /* common */
26 
27 /* client */
28 #include "client_main.h"
29 #include "climisc.h"
30 
31 /* gui-sdl */
32 #include "colors.h"
33 #include "diplodlg.h"
34 #include "graphics.h"
35 #include "gui_id.h"
36 #include "gui_main.h"
37 #include "gui_tilespec.h"
38 #include "inteldlg.h"
39 #include "mapview.h"
40 #include "sprite.h"
41 #include "themespec.h"
42 #include "widget.h"
43 
44 #include "plrdlg.h"
45 
46 #ifndef M_PI
47 #define M_PI		3.14159265358979323846	/* pi */
48 #endif
49 #ifndef M_PI_2
50 #define M_PI_2		1.57079632679489661923	/* pi/2 */
51 #endif
52 
53 static struct SMALL_DLG  *pPlayers_Dlg = NULL;
54 
exit_players_dlg_callback(struct widget * pWidget)55 static int exit_players_dlg_callback(struct widget *pWidget)
56 {
57   if (Main.event.button.button == SDL_BUTTON_LEFT) {
58     popdown_players_dialog();
59     flush_dirty();
60   }
61   return -1;
62 }
63 
player_callback(struct widget * pWidget)64 static int player_callback(struct widget *pWidget)
65 {
66   struct player *pPlayer = pWidget->data.player;
67   if (Main.event.type == SDL_MOUSEBUTTONDOWN) {
68     switch (Main.event.button.button) {
69 #if 0
70     case SDL_BUTTON_LEFT:
71 
72       break;
73     case SDL_BUTTON_MIDDLE:
74 
75       break;
76 #endif
77     case SDL_BUTTON_RIGHT:
78       if (can_intel_with_player(pPlayer)) {
79         popdown_players_dialog();
80         popup_intel_dialog(pPlayer);
81         return -1;
82       }
83       break;
84     default:
85       popdown_players_dialog();
86       popup_diplomacy_dialog(pPlayer);
87       return -1;
88       break;
89     }
90   }
91 
92   return -1;
93 }
94 
players_window_dlg_callback(struct widget * pWindow)95 static int players_window_dlg_callback(struct widget *pWindow)
96 {
97   if (Main.event.button.button == SDL_BUTTON_LEFT) {
98     if (move_window_group_dialog(pPlayers_Dlg->pBeginWidgetList, pWindow)) {
99       sellect_window_group_dialog(pPlayers_Dlg->pBeginWidgetList, pWindow);
100       players_dialog_update();
101     } else {
102       if(sellect_window_group_dialog(pPlayers_Dlg->pBeginWidgetList, pWindow)) {
103         widget_flush(pWindow);
104       }
105     }
106   }
107   return -1;
108 }
109 
toggle_draw_war_status_callback(struct widget * pWidget)110 static int toggle_draw_war_status_callback(struct widget *pWidget)
111 {
112   if (Main.event.button.button == SDL_BUTTON_LEFT) {
113     /* exit button -> neutral -> war -> casefire -> peace -> alliance */
114     struct widget *pPlayer = pPlayers_Dlg->pEndWidgetList->prev->prev->prev->prev->prev->prev;
115     SDL_Client_Flags ^= CF_DRAW_PLAYERS_WAR_STATUS;
116     do{
117       pPlayer = pPlayer->prev;
118       FREESURFACE(pPlayer->gfx);
119     } while(pPlayer != pPlayers_Dlg->pBeginWidgetList);
120     players_dialog_update();
121   }
122   return -1;
123 }
124 
toggle_draw_ceasefire_status_callback(struct widget * pWidget)125 static int toggle_draw_ceasefire_status_callback(struct widget *pWidget)
126 {
127   if (Main.event.button.button == SDL_BUTTON_LEFT) {
128     /* exit button -> neutral -> war -> casefire -> peace -> alliance */
129     struct widget *pPlayer = pPlayers_Dlg->pEndWidgetList->prev->prev->prev->prev->prev->prev;
130     SDL_Client_Flags ^= CF_DRAW_PLAYERS_CEASEFIRE_STATUS;
131     do{
132       pPlayer = pPlayer->prev;
133       FREESURFACE(pPlayer->gfx);
134     } while(pPlayer != pPlayers_Dlg->pBeginWidgetList);
135     players_dialog_update();
136   }
137   return -1;
138 }
139 
toggle_draw_pease_status_callback(struct widget * pWidget)140 static int toggle_draw_pease_status_callback(struct widget *pWidget)
141 {
142   if (Main.event.button.button == SDL_BUTTON_LEFT) {
143     /* exit button -> neutral -> war -> casefire -> peace -> alliance */
144     struct widget *pPlayer = pPlayers_Dlg->pEndWidgetList->prev->prev->prev->prev->prev->prev;
145     SDL_Client_Flags ^= CF_DRAW_PLAYERS_PEACE_STATUS;
146     do{
147       pPlayer = pPlayer->prev;
148       FREESURFACE(pPlayer->gfx);
149     } while(pPlayer != pPlayers_Dlg->pBeginWidgetList);
150     players_dialog_update();
151   }
152   return -1;
153 }
154 
toggle_draw_alliance_status_callback(struct widget * pWidget)155 static int toggle_draw_alliance_status_callback(struct widget *pWidget)
156 {
157   if (Main.event.button.button == SDL_BUTTON_LEFT) {
158     /* exit button -> neutral -> war -> casefire -> peace -> alliance */
159     struct widget *pPlayer = pPlayers_Dlg->pEndWidgetList->prev->prev->prev->prev->prev->prev;
160     SDL_Client_Flags ^= CF_DRAW_PLAYERS_ALLIANCE_STATUS;
161     do{
162       pPlayer = pPlayer->prev;
163       FREESURFACE(pPlayer->gfx);
164     } while(pPlayer != pPlayers_Dlg->pBeginWidgetList);
165     players_dialog_update();
166   }
167   return -1;
168 }
169 
toggle_draw_neutral_status_callback(struct widget * pWidget)170 static int toggle_draw_neutral_status_callback(struct widget *pWidget)
171 {
172   if (Main.event.button.button == SDL_BUTTON_LEFT) {
173     /* exit button -> neutral -> war -> casefire -> peace -> alliance */
174     struct widget *pPlayer = pPlayers_Dlg->pEndWidgetList->prev->prev->prev->prev->prev->prev;
175 
176     SDL_Client_Flags ^= CF_DRAW_PLAYERS_NEUTRAL_STATUS;
177     do{
178       pPlayer = pPlayer->prev;
179       FREESURFACE(pPlayer->gfx);
180     } while(pPlayer != pPlayers_Dlg->pBeginWidgetList);
181     players_dialog_update();
182   }
183   return -1;
184 }
185 
186 
have_diplomat_info_about(struct player * pPlayer)187 static bool have_diplomat_info_about(struct player *pPlayer)
188 {
189   return (pPlayer == client.conn.playing
190 	  || (pPlayer != client.conn.playing
191 	   && player_has_embassy(client.conn.playing, pPlayer)));
192 }
193 
194 /**************************************************************************
195   Update all information in the player list dialog.
196 **************************************************************************/
real_players_dialog_update(void * unused)197 void real_players_dialog_update(void *unused)
198 {
199   if(pPlayers_Dlg) {
200     struct widget *pPlayer0, *pPlayer1;
201     struct player *pPlayer;
202     SDL_Rect dst0, dst1;
203     int i;
204     struct astring astr = ASTRING_INIT;
205 
206     /* redraw window */
207     widget_redraw(pPlayers_Dlg->pEndWidgetList);
208 
209     /* exit button -> neutral -> war -> casefire -> peace -> alliance */
210     pPlayer0 = pPlayers_Dlg->pEndWidgetList->prev->prev->prev->prev->prev->prev;
211     do{
212       pPlayer0 = pPlayer0->prev;
213       pPlayer1 = pPlayer0;
214       pPlayer = pPlayer0->data.player;
215 
216       for (i = 0; i < num_player_dlg_columns; i++) {
217         if (player_dlg_columns[i].show) {
218           switch (player_dlg_columns[i].type) {
219             case COL_TEXT:
220             case COL_RIGHT_TEXT:
221               astr_add_line(&astr, "%s: %s", player_dlg_columns[i].title,
222                                              player_dlg_columns[i].func(pPlayer));
223               break;
224             case COL_BOOLEAN:
225               astr_add_line(&astr, "%s: %s", player_dlg_columns[i].title,
226                             player_dlg_columns[i].bool_func(pPlayer) ?
227                               _("Yes") : _("No"));
228               break;
229             default:
230               break;
231           }
232         }
233       }
234 
235       copy_chars_to_string16(pPlayer0->info_label, astr_str(&astr));
236 
237       astr_free(&astr);
238 
239       /* now add some eye candy ... */
240       if(pPlayer1 != pPlayers_Dlg->pBeginWidgetList) {
241         dst0.x = pPlayer0->size.x + pPlayer0->size.w / 2;
242         dst0.y = pPlayer0->size.y + pPlayer0->size.h / 2;
243 
244         do{
245           pPlayer1 = pPlayer1->prev;
246 	  if (have_diplomat_info_about(pPlayer) ||
247 	     have_diplomat_info_about(pPlayer1->data.player)) {
248             dst1.x = pPlayer1->size.x + pPlayer1->size.w / 2;
249             dst1.y = pPlayer1->size.y + pPlayer1->size.h / 2;
250 
251             switch (player_diplstate_get(pPlayer,
252                                          pPlayer1->data.player)->type) {
253 	      case DS_ARMISTICE:
254 	        if(SDL_Client_Flags & CF_DRAW_PLAYERS_NEUTRAL_STATUS) {
255 	          putline(pPlayer1->dst->surface,
256 	                  dst0.x, dst0.y, dst1.x, dst1.y,
257 	                  get_theme_color(COLOR_THEME_PLRDLG_ARMISTICE));
258 	        }
259 	      break;
260               case DS_WAR:
261 	        if(SDL_Client_Flags & CF_DRAW_PLAYERS_WAR_STATUS) {
262 	          putline(pPlayer1->dst->surface,
263 	                  dst0.x, dst0.y, dst1.x, dst1.y,
264 	                  get_theme_color(COLOR_THEME_PLRDLG_WAR));
265 	        }
266               break;
267 	      case DS_CEASEFIRE:
268 	        if (SDL_Client_Flags & CF_DRAW_PLAYERS_CEASEFIRE_STATUS) {
269 	          putline(pPlayer1->dst->surface,
270 	                  dst0.x, dst0.y, dst1.x, dst1.y,
271 	                  get_theme_color(COLOR_THEME_PLRDLG_CEASEFIRE));
272 	        }
273               break;
274               case DS_PEACE:
275 	        if (SDL_Client_Flags & CF_DRAW_PLAYERS_PEACE_STATUS) {
276 	          putline(pPlayer1->dst->surface,
277 	                  dst0.x, dst0.y, dst1.x, dst1.y,
278 	                  get_theme_color(COLOR_THEME_PLRDLG_PEACE));
279 	        }
280               break;
281 	      case DS_ALLIANCE:
282 	        if (SDL_Client_Flags & CF_DRAW_PLAYERS_ALLIANCE_STATUS) {
283 	          putline(pPlayer1->dst->surface,
284 	                  dst0.x, dst0.y, dst1.x, dst1.y,
285 	                  get_theme_color(COLOR_THEME_PLRDLG_ALLIANCE));
286 	        }
287               break;
288               default:
289 	        /* no contact */
290               break;
291 	    }
292 	  }
293 
294         } while(pPlayer1 != pPlayers_Dlg->pBeginWidgetList);
295       }
296 
297     } while(pPlayer0 != pPlayers_Dlg->pBeginWidgetList);
298 
299     /* -------------------- */
300     /* redraw */
301     redraw_group(pPlayers_Dlg->pBeginWidgetList,
302     			pPlayers_Dlg->pEndWidgetList->prev, 0);
303     widget_mark_dirty(pPlayers_Dlg->pEndWidgetList);
304 
305     flush_dirty();
306   }
307 }
308 
309 /**************************************************************************
310   Popup (or raise) the player list dialog.
311 **************************************************************************/
popup_players_dialog(bool raise)312 void popup_players_dialog(bool raise)
313 {
314   struct widget *pWindow = NULL, *pBuf = NULL;
315   SDL_Surface *pLogo = NULL, *pZoomed = NULL;
316   SDL_String16 *pStr;
317   SDL_Rect dst;
318   int i, n, h;
319   double a, b, r;
320   SDL_Rect area;
321 
322   if (pPlayers_Dlg) {
323     return;
324   }
325 
326   n = 0;
327   players_iterate(pPlayer) {
328     if(is_barbarian(pPlayer)) {
329       continue;
330     }
331     n++;
332   } players_iterate_end;
333 
334   if (n < 2) {
335     return;
336   }
337 
338   pPlayers_Dlg = fc_calloc(1, sizeof(struct SMALL_DLG));
339 
340   pStr = create_str16_from_char(Q_("?header:Players"), adj_font(12));
341   pStr->style |= TTF_STYLE_BOLD;
342 
343   pWindow = create_window_skeleton(NULL, pStr, 0);
344 
345   pWindow->action = players_window_dlg_callback;
346   set_wstate(pWindow, FC_WS_NORMAL);
347 
348   add_to_gui_list(ID_WINDOW, pWindow);
349   pPlayers_Dlg->pEndWidgetList = pWindow;
350   /* ---------- */
351   /* exit button */
352   pBuf = create_themeicon(current_theme->Small_CANCEL_Icon, pWindow->dst,
353                           WF_WIDGET_HAS_INFO_LABEL | WF_RESTORE_BACKGROUND);
354   pBuf->info_label = create_str16_from_char(_("Close Dialog (Esc)"),
355                                             adj_font(12));
356   pBuf->action = exit_players_dlg_callback;
357   set_wstate(pBuf, FC_WS_NORMAL);
358   pBuf->key = SDLK_ESCAPE;
359 
360   add_to_gui_list(ID_BUTTON, pBuf);
361   /* ---------- */
362 
363   for(i = 0; i<DS_LAST; i++) {
364     switch (i) {
365       case DS_ARMISTICE:
366 	pBuf = create_checkbox(pWindow->dst,
367 		(SDL_Client_Flags & CF_DRAW_PLAYERS_NEUTRAL_STATUS),
368       						WF_RESTORE_BACKGROUND);
369 	pBuf->action = toggle_draw_neutral_status_callback;
370 	pBuf->key = SDLK_n;
371       break;
372       case DS_WAR:
373 	pBuf = create_checkbox(pWindow->dst,
374 		(SDL_Client_Flags & CF_DRAW_PLAYERS_WAR_STATUS),
375       						WF_RESTORE_BACKGROUND);
376 	pBuf->action = toggle_draw_war_status_callback;
377 	pBuf->key = SDLK_w;
378       break;
379       case DS_CEASEFIRE:
380 	pBuf = create_checkbox(pWindow->dst,
381 		(SDL_Client_Flags & CF_DRAW_PLAYERS_CEASEFIRE_STATUS),
382       						WF_RESTORE_BACKGROUND);
383 	pBuf->action = toggle_draw_ceasefire_status_callback;
384 	pBuf->key = SDLK_c;
385       break;
386       case DS_PEACE:
387 	pBuf = create_checkbox(pWindow->dst,
388 		(SDL_Client_Flags & CF_DRAW_PLAYERS_PEACE_STATUS),
389       						WF_RESTORE_BACKGROUND);
390 	pBuf->action = toggle_draw_pease_status_callback;
391 	pBuf->key = SDLK_p;
392       break;
393       case DS_ALLIANCE:
394 	pBuf = create_checkbox(pWindow->dst,
395 		(SDL_Client_Flags & CF_DRAW_PLAYERS_ALLIANCE_STATUS),
396       						WF_RESTORE_BACKGROUND);
397 	pBuf->action = toggle_draw_alliance_status_callback;
398 	pBuf->key = SDLK_a;
399       break;
400       default:
401 	 /* no contact */
402 	 continue;
403       break;
404     }
405     set_wstate(pBuf, FC_WS_NORMAL);
406     add_to_gui_list(ID_CHECKBOX, pBuf);
407   }
408   /* ---------- */
409 
410   players_iterate(pPlayer) {
411     if(is_barbarian(pPlayer)) {
412       continue;
413     }
414 
415     pStr = create_string16(NULL, 0, adj_font(10));
416     pStr->style |= (TTF_STYLE_BOLD|SF_CENTER);
417 
418     pLogo = get_nation_flag_surface(nation_of_player(pPlayer));
419     {
420       /* Aim for a flag height of 60 pixels, but draw smaller flags if there
421        * are more players */
422       double zoom = DEFAULT_ZOOM * (60.0 - n) / pLogo->h;
423       pZoomed = zoomSurface(pLogo, zoom, zoom, 1);
424     }
425 
426     pBuf = create_icon2(pZoomed, pWindow->dst,
427                         WF_RESTORE_BACKGROUND | WF_WIDGET_HAS_INFO_LABEL
428                         | WF_FREE_THEME);
429     pBuf->info_label = pStr;
430 
431     if(!pPlayer->is_alive) {
432       pStr = create_str16_from_char(_("R.I.P.") , adj_font(10));
433       pStr->style |= TTF_STYLE_BOLD;
434       pStr->fgcol = *get_theme_color(COLOR_THEME_PLRDLG_TEXT);
435       pLogo = create_text_surf_from_str16(pStr);
436       FREESTRING16(pStr);
437 
438       dst.x = (pZoomed->w - pLogo->w) / 2;
439       dst.y = (pZoomed->h - pLogo->h) / 2;
440       alphablit(pLogo, NULL, pZoomed, &dst);
441       FREESURFACE(pLogo);
442     }
443 
444     if(pPlayer->is_alive) {
445       set_wstate(pBuf, FC_WS_NORMAL);
446     }
447 
448     pBuf->data.player = pPlayer;
449 
450     pBuf->action = player_callback;
451 
452     add_to_gui_list(ID_LABEL, pBuf);
453 
454   } players_iterate_end;
455 
456   pPlayers_Dlg->pBeginWidgetList = pBuf;
457 
458   resize_window(pWindow, NULL, NULL, adj_size(500), adj_size(400));
459 
460   area = pWindow->area;
461 
462   r = MIN(area.w, area.h);
463   r -= ((MAX(pBuf->size.w, pBuf->size.h) * 2));
464   r /= 2;
465   a = (2.0 * M_PI) / n;
466 
467   widget_set_position(pWindow,
468                       (Main.screen->w - pWindow->size.w) / 2,
469                       (Main.screen->h - pWindow->size.h) / 2);
470 
471   /* exit button */
472   pBuf = pWindow->prev;
473 
474   pBuf->size.x = area.x + area.w - pBuf->size.w - 1;
475   pBuf->size.y = pWindow->size.y + adj_size(2);
476 
477   n = area.y;
478   pStr = create_string16(NULL, 0, adj_font(10));
479   pStr->style |= TTF_STYLE_BOLD;
480   pStr->bgcol = (SDL_Color) {0, 0, 0, 0};
481 
482   for(i = 0; i<DS_LAST; i++) {
483       switch (i) {
484 	case DS_ARMISTICE:
485 	  pStr->fgcol = *get_theme_color(COLOR_THEME_PLRDLG_ARMISTICE);
486 	break;
487         case DS_WAR:
488 	  pStr->fgcol = *get_theme_color(COLOR_THEME_PLRDLG_WAR);
489 	break;
490 	case DS_CEASEFIRE:
491 	  pStr->fgcol = *get_theme_color(COLOR_THEME_PLRDLG_CEASEFIRE);
492 	break;
493         case DS_PEACE:
494 	  pStr->fgcol = *get_theme_color(COLOR_THEME_PLRDLG_PEACE);
495         break;
496 	case DS_ALLIANCE:
497 	  pStr->fgcol = *get_theme_color(COLOR_THEME_PLRDLG_ALLIANCE);
498 	break;
499         default:
500 	   /* no contact */
501 	   continue;
502         break;
503       }
504 
505       copy_chars_to_string16(pStr, diplstate_type_translated_name(i));
506       pLogo = create_text_surf_from_str16(pStr);
507 
508       pBuf = pBuf->prev;
509       h = MAX(pBuf->size.h, pLogo->h);
510       pBuf->size.x = area.x + adj_size(5);
511       pBuf->size.y = n + (h - pBuf->size.h) / 2;
512 
513       dst.x = adj_size(5) + pBuf->size.w + adj_size(6);
514       dst.y = n + (h - pLogo->h) / 2;
515       alphablit(pLogo, NULL, pWindow->theme, &dst);
516       n += h;
517       FREESURFACE(pLogo);
518   }
519   FREESTRING16(pStr);
520 
521   /* first player shield */
522   pBuf = pBuf->prev;
523   pBuf->size.x = area.x + area.w / 2 - pBuf->size.w / 2;
524   pBuf->size.y = area.y + area.h / 2 - r - pBuf->size.h / 2;
525 
526   n = 1;
527   if(pBuf != pPlayers_Dlg->pBeginWidgetList) {
528     do{
529       pBuf = pBuf->prev;
530       b = M_PI_2 + n * a;
531       pBuf->size.x = area.x + area.w / 2 - r * cos(b) - pBuf->size.w / 2;
532       pBuf->size.y = area.y + area.h / 2 - r * sin(b) - pBuf->size.h / 2;
533       n++;
534     } while(pBuf != pPlayers_Dlg->pBeginWidgetList);
535   }
536 
537   players_dialog_update();
538 }
539 
540 /**************************************************************************
541   Popdownown the player list dialog.
542 **************************************************************************/
popdown_players_dialog(void)543 void popdown_players_dialog(void)
544 {
545   if (pPlayers_Dlg) {
546     popdown_window_group_dialog(pPlayers_Dlg->pBeginWidgetList,
547 			pPlayers_Dlg->pEndWidgetList);
548     FC_FREE(pPlayers_Dlg);
549   }
550 }
551 
552 
553 /* ============================== SHORT =============================== */
554 static struct ADVANCED_DLG  *pShort_Players_Dlg = NULL;
555 
players_nations_window_dlg_callback(struct widget * pWindow)556 static int players_nations_window_dlg_callback(struct widget *pWindow)
557 {
558   return -1;
559 }
560 
exit_players_nations_dlg_callback(struct widget * pWidget)561 static int exit_players_nations_dlg_callback(struct widget *pWidget)
562 {
563   if (Main.event.button.button == SDL_BUTTON_LEFT) {
564     popdown_players_nations_dialog();
565     flush_dirty();
566   }
567   return -1;
568 }
569 
player_nation_callback(struct widget * pWidget)570 static int player_nation_callback(struct widget *pWidget)
571 {
572   struct player *pPlayer = pWidget->data.player;
573   popdown_players_nations_dialog();
574   if (Main.event.type == SDL_MOUSEBUTTONDOWN) {
575     switch (Main.event.button.button) {
576 #if 0
577       case SDL_BUTTON_LEFT:
578 
579       break;
580       case SDL_BUTTON_MIDDLE:
581 
582       break;
583 #endif
584       case SDL_BUTTON_RIGHT:
585         if (can_intel_with_player(pPlayer)) {
586           popup_intel_dialog(pPlayer);
587         } else {
588           flush_dirty();
589         }
590       break;
591       default:
592         if (pPlayer != client.conn.playing) {
593           popup_diplomacy_dialog(pPlayer);
594         }
595       break;
596     }
597   }
598 
599   return -1;
600 }
601 
602 /**************************************************************************
603   Popup (or raise) the short player list dialog version.
604 **************************************************************************/
popup_players_nations_dialog(void)605 void popup_players_nations_dialog(void)
606 {
607   struct widget *pWindow = NULL, *pBuf = NULL;
608   SDL_Surface *pLogo = NULL;
609   SDL_String16 *pStr;
610   char cBuf[128], *state;
611   int n = 0, w = 0, units_h = 0;
612   const struct player_diplstate *pDS;
613   SDL_Rect area;
614 
615   if (pShort_Players_Dlg) {
616     return;
617   }
618 
619   pShort_Players_Dlg = fc_calloc(1, sizeof(struct ADVANCED_DLG));
620 
621   /* TRANS: Nations report title */
622   pStr = create_str16_from_char(_("Nations") , adj_font(12));
623   pStr->style |= TTF_STYLE_BOLD;
624 
625   pWindow = create_window_skeleton(NULL, pStr, 0);
626 
627   pWindow->action = players_nations_window_dlg_callback;
628   set_wstate(pWindow, FC_WS_NORMAL);
629 
630   add_to_gui_list(ID_WINDOW, pWindow);
631   pShort_Players_Dlg->pEndWidgetList = pWindow;
632 
633   area = pWindow->area;
634 
635   /* ---------- */
636   /* exit button */
637   pBuf = create_themeicon(current_theme->Small_CANCEL_Icon, pWindow->dst,
638                           WF_WIDGET_HAS_INFO_LABEL | WF_RESTORE_BACKGROUND);
639   pBuf->info_label = create_str16_from_char(_("Close Dialog (Esc)"),
640                                             adj_font(12));
641   area.w = MAX(area.w, pBuf->size.w + adj_size(10));
642   pBuf->action = exit_players_nations_dlg_callback;
643   set_wstate(pBuf, FC_WS_NORMAL);
644   pBuf->key = SDLK_ESCAPE;
645 
646   add_to_gui_list(ID_BUTTON, pBuf);
647   /* ---------- */
648 
649   players_iterate(pPlayer) {
650     if (pPlayer != client.conn.playing) {
651       if(!pPlayer->is_alive || is_barbarian(pPlayer)) {
652         continue;
653       }
654 
655       pDS = player_diplstate_get(client.conn.playing, pPlayer);
656 
657       if(pPlayer->ai_controlled) {
658 	state = _("AI");
659       } else {
660         if (pPlayer->is_connected) {
661           if (pPlayer->phase_done) {
662       	    state = _("done");
663           } else {
664       	    state = _("moving");
665           }
666         } else {
667           state = _("disconnected");
668         }
669       }
670 
671       if(pDS->type == DS_CEASEFIRE) {
672 	fc_snprintf(cBuf, sizeof(cBuf), "%s(%s) - %d %s",
673                     nation_adjective_for_player(pPlayer),
674                     state,
675 		pDS->turns_left, PL_("turn", "turns", pDS->turns_left));
676       } else {
677 	fc_snprintf(cBuf, sizeof(cBuf), "%s(%s)",
678                     nation_adjective_for_player(pPlayer),
679                     state);
680       }
681 
682       pStr = create_str16_from_char(cBuf, adj_font(10));
683       pStr->style |= TTF_STYLE_BOLD;
684 
685       pLogo = get_nation_flag_surface(nation_of_player(pPlayer));
686 
687       pBuf = create_iconlabel(pLogo, pWindow->dst, pStr,
688     	(/*WF_FREE_THEME|*/WF_RESTORE_BACKGROUND|WF_DRAW_TEXT_LABEL_WITH_SPACE));
689 
690       /* now add some eye candy ... */
691       switch (pDS->type) {
692 	case DS_ARMISTICE:
693 	  pBuf->string16->fgcol = *get_theme_color(COLOR_THEME_PLRDLG_ARMISTICE);
694 	  set_wstate(pBuf, FC_WS_NORMAL);
695         break;
696         case DS_WAR:
697 	  if(can_meet_with_player(pPlayer) || can_intel_with_player(pPlayer)) {
698             set_wstate(pBuf, FC_WS_NORMAL);
699 	    pBuf->string16->fgcol = *get_theme_color(COLOR_THEME_PLRDLG_WAR);
700           } else {
701 	    pBuf->string16->fgcol = *(get_theme_color(COLOR_THEME_PLRDLG_WAR_RESTRICTED));
702 	  }
703         break;
704 	case DS_CEASEFIRE:
705 	  pBuf->string16->fgcol = *get_theme_color(COLOR_THEME_PLRDLG_CEASEFIRE);
706 	  set_wstate(pBuf, FC_WS_NORMAL);
707         break;
708         case DS_PEACE:
709 	  pBuf->string16->fgcol = *get_theme_color(COLOR_THEME_PLRDLG_PEACE);
710 	  set_wstate(pBuf, FC_WS_NORMAL);
711         break;
712 	case DS_ALLIANCE:
713 	  pBuf->string16->fgcol = *get_theme_color(COLOR_THEME_PLRDLG_ALLIANCE);
714 	  set_wstate(pBuf, FC_WS_NORMAL);
715         break;
716 	case DS_NO_CONTACT:
717 	  pBuf->string16->fgcol = *(get_theme_color(COLOR_THEME_WIDGET_DISABLED_TEXT));
718 	break;
719         default:
720 	  set_wstate(pBuf, FC_WS_NORMAL);
721         break;
722       }
723 
724       pBuf->string16->bgcol = (SDL_Color) {0, 0, 0, 0};
725 
726       pBuf->data.player = pPlayer;
727 
728       pBuf->action = player_nation_callback;
729 
730 
731       add_to_gui_list(ID_LABEL, pBuf);
732 
733       area.w = MAX(w, pBuf->size.w);
734       area.h += pBuf->size.h;
735 
736       if (n > 19)
737       {
738         set_wflag(pBuf, WF_HIDDEN);
739       }
740 
741       n++;
742     }
743   } players_iterate_end;
744   pShort_Players_Dlg->pBeginWidgetList = pBuf;
745   pShort_Players_Dlg->pBeginActiveWidgetList = pShort_Players_Dlg->pBeginWidgetList;
746   pShort_Players_Dlg->pEndActiveWidgetList = pWindow->prev->prev;
747   pShort_Players_Dlg->pActiveWidgetList = pShort_Players_Dlg->pEndActiveWidgetList;
748 
749 
750   /* ---------- */
751   if (n > 20)
752   {
753 
754     units_h = create_vertical_scrollbar(pShort_Players_Dlg, 1, 20, TRUE, TRUE);
755     pShort_Players_Dlg->pScroll->count = n;
756 
757     n = units_h;
758     area.w += n;
759 
760     units_h = 20 * pBuf->size.h;
761 
762   } else {
763     units_h = area.h;
764   }
765 
766   /* ---------- */
767 
768   area.h = units_h;
769 
770   resize_window(pWindow, NULL, NULL,
771                 (pWindow->size.w - pWindow->area.w) + area.w,
772                 (pWindow->size.h + pWindow->area.h) + area.h);
773 
774   area = pWindow->area;
775 
776   widget_set_position(pWindow,
777     ((Main.event.motion.x + pWindow->size.w + adj_size(10) < Main.screen->w) ?
778       (Main.event.motion.x + adj_size(10)) :
779       (Main.screen->w - pWindow->size.w - adj_size(10))),
780     ((Main.event.motion.y - adj_size(2) + pWindow->size.h < Main.screen->h) ?
781       (Main.event.motion.y - adj_size(2)) :
782       (Main.screen->h - pWindow->size.h - adj_size(10))));
783 
784   w = area.w;
785 
786   if (pShort_Players_Dlg->pScroll)
787   {
788     w -= n;
789   }
790 
791   /* exit button */
792   pBuf = pWindow->prev;
793   pBuf->size.x = area.x + area.w - pBuf->size.w - 1;
794   pBuf->size.y = pWindow->size.y + adj_size(2);
795 
796   /* cities */
797   pBuf = pBuf->prev;
798   setup_vertical_widgets_position(1,
799 	area.x, area.y,
800 	w, 0, pShort_Players_Dlg->pBeginActiveWidgetList, pBuf);
801 
802   if (pShort_Players_Dlg->pScroll)
803   {
804     setup_vertical_scrollbar_area(pShort_Players_Dlg->pScroll,
805 	area.x + area.w, area.y,
806     	area.h, TRUE);
807   }
808 
809   /* -------------------- */
810   /* redraw */
811   redraw_group(pShort_Players_Dlg->pBeginWidgetList, pWindow, 0);
812   widget_mark_dirty(pWindow);
813 
814   flush_dirty();
815 }
816 
817 /**************************************************************************
818   Popdown the short player list dialog version.
819 **************************************************************************/
popdown_players_nations_dialog(void)820 void popdown_players_nations_dialog(void)
821 {
822   if (pShort_Players_Dlg) {
823     popdown_window_group_dialog(pShort_Players_Dlg->pBeginWidgetList,
824 			pShort_Players_Dlg->pEndWidgetList);
825     FC_FREE(pShort_Players_Dlg->pScroll);
826     FC_FREE(pShort_Players_Dlg);
827   }
828 }
829