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)
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 ***********************************************************************/
15 #include <fc_config.h>
21 #include <X11/Intrinsic.h>
22 #include <X11/StringDefs.h>
23 #include <X11/Xaw/Form.h>
24 #include <X11/Xaw/Label.h>
25 #include <X11/Xaw/Command.h>
26 #include <X11/Xaw/MenuButton.h>
27 #include <X11/Xaw/SimpleMenu.h>
28 #include <X11/Xaw/SmeBSB.h>
29 #include <X11/Xaw/List.h>
30 #include <X11/Xaw/Viewport.h>
31 #include <X11/Xaw/AsciiText.h>
32 #include <X11/Xaw/Toggle.h>
33 #include <X11/IntrinsicP.h>
36 #include "bitvector.h"
46 #include "connection.h" /* can_conn_edit */
51 #include "specialist.h"
52 #include "traderoutes.h"
56 #include "client_main.h"
59 #include "control.h" /* request_xxx and unit_focus_set */
73 #include "gui_stuff.h"
78 #include "optiondlg.h" /* for toggle_callback */
83 #include "citydlg_common.h"
86 #define MIN_NUM_CITIZENS 22
87 #define MAX_NUM_CITIZENS 50
88 #define DEFAULT_NUM_CITIZENS 38
89 #define MIN_NUM_UNITS 8
90 #define MAX_NUM_UNITS 20
91 #define DEFAULT_NUM_UNITS 11
96 int num_citizens_shown
;
102 Widget cityname_label
;
103 Widget
*citizen_labels
;
104 Widget production_label
;
106 Widget storage_label
;
107 Widget pollution_label
;
111 Widget close_command
, rename_command
, trade_command
, activate_command
;
112 Widget show_units_command
, cityopt_command
, cma_command
;
113 Widget building_label
, progress_label
, buy_command
, change_command
,
114 worklist_command
, worklist_label
;
115 Widget improvement_viewport
, improvement_list
;
116 Widget support_unit_label
;
117 Widget
*support_unit_pixcomms
;
118 Widget support_unit_next_command
;
119 Widget support_unit_prev_command
;
120 Widget present_unit_label
;
121 Widget
*present_unit_pixcomms
;
122 Widget present_unit_next_command
;
123 Widget present_unit_prev_command
;
126 Widget worklist_shell
;
128 Impr_type_id sell_id
;
130 int support_unit_base
;
131 int present_unit_base
;
132 char improvlist_names
[B_LAST
+1][64];
133 char *improvlist_names_ptrs
[B_LAST
+1];
135 char *change_list_names_ptrs
[B_LAST
+1+U_LAST
+1+1];
136 char change_list_names
[B_LAST
+1+U_LAST
+1][200];
137 int change_list_ids
[B_LAST
+1+U_LAST
+1];
138 int change_list_num_improvements
;
143 #define SPECLIST_TAG dialog
144 #define SPECLIST_TYPE struct city_dialog
145 #include "speclist.h"
147 #define dialog_list_iterate(dialoglist, pdialog) \
148 TYPED_LIST_ITERATE(struct city_dialog, dialoglist, pdialog)
149 #define dialog_list_iterate_end LIST_ITERATE_END
151 static struct dialog_list
*dialog_list
= NULL
;
152 static bool dialog_list_has_been_initialised
= FALSE
;
154 static struct city_dialog
*get_city_dialog(struct city
*pcity
);
155 static struct city_dialog
*create_city_dialog(struct city
*pcity
);
156 static void close_city_dialog(struct city_dialog
*pdialog
);
158 static void city_dialog_update_improvement_list(struct city_dialog
*pdialog
);
159 static void city_dialog_update_title(struct city_dialog
*pdialog
);
160 static void city_dialog_update_supported_units(struct city_dialog
*pdialog
, int id
);
161 static void city_dialog_update_present_units(struct city_dialog
*pdialog
, int id
);
162 static void city_dialog_update_citizens(struct city_dialog
*pdialog
);
163 static void city_dialog_update_production(struct city_dialog
*pdialog
);
164 static void city_dialog_update_output(struct city_dialog
*pdialog
);
165 static void city_dialog_update_building(struct city_dialog
*pdialog
);
166 static void city_dialog_update_storage(struct city_dialog
*pdialog
);
167 static void city_dialog_update_pollution(struct city_dialog
*pdialog
);
169 static void sell_callback(Widget w
, XtPointer client_data
, XtPointer call_data
);
170 static void buy_callback(Widget w
, XtPointer client_data
, XtPointer call_data
);
171 static void change_callback(Widget w
, XtPointer client_data
, XtPointer call_data
);
172 static void worklist_callback(Widget w
, XtPointer client_data
, XtPointer call_data
);
173 void commit_city_worklist(struct worklist
*pwl
, void *data
);
174 void cancel_city_worklist(void *data
);
175 static void close_callback(Widget w
, XtPointer client_data
, XtPointer call_data
);
176 static void rename_callback(Widget w
, XtPointer client_data
, XtPointer call_data
);
177 static void trade_callback(Widget w
, XtPointer client_data
, XtPointer call_data
);
178 static void activate_callback(Widget w
, XtPointer client_data
, XtPointer call_data
);
179 static void show_units_callback(Widget W
, XtPointer client_data
, XtPointer call_data
);
180 static void units_next_prev_callback(Widget W
, XtPointer client_data
,
181 XtPointer call_data
);
182 static void unitupgrade_callback_yes(Widget w
, XtPointer client_data
,
183 XtPointer call_data
);
184 static void unitupgrade_callback_no(Widget w
, XtPointer client_data
,
185 XtPointer call_data
);
186 static void upgrade_callback(Widget w
, XtPointer client_data
, XtPointer call_data
);
187 static void disband_callback(Widget w
, XtPointer client_data
, XtPointer call_data
);
189 static void present_units_callback(Widget w
, XtPointer client_data
,
190 XtPointer call_data
);
191 static void cityopt_callback(Widget w
, XtPointer client_data
,
192 XtPointer call_data
);
193 static void cma_callback(Widget w
, XtPointer client_data
,
194 XtPointer call_data
);
195 static void popdown_cityopt_dialog(void);
197 /****************************************************************
199 *****************************************************************/
200 static void get_contents_of_pollution(struct city_dialog
*pdialog
,
211 pcity
=pdialog
->pcity
;
212 corruption
=pcity
->waste
[O_TRADE
];
213 waste
=pcity
->waste
[O_SHIELD
];
214 pollution
=pcity
->pollution
;
215 if (!game
.info
.illness_on
) {
216 fc_snprintf(buf
, sizeof(buf
), " -.-");
218 illness
= city_illness_calc(pcity
, NULL
, NULL
, NULL
, NULL
);
219 /* illness is in tenth of percent */
220 fc_snprintf(buf
, sizeof(buf
), "%4.1f",
221 (float)illness
/ 10.0);
225 fc_snprintf(retbuf
, n
, _("Corruption: %4d\n"
229 corruption
, waste
, pollution
, buf
);
232 /****************************************************************
234 *****************************************************************/
235 static void get_contents_of_storage(struct city_dialog
*pdialog
,
245 pcity
=pdialog
->pcity
;
246 foodstock
=pcity
->food_stock
;
247 foodbox
=city_granary_size(city_size_get(pcity
));
248 granaryturns
= city_turns_to_grow(pcity
);
249 if (granaryturns
== 0) {
250 fc_snprintf(buf
, sizeof(buf
), _("blocked"));
251 } else if (granaryturns
== FC_INFINITY
) {
252 fc_snprintf(buf
, sizeof(buf
), _("never"));
254 /* A negative value means we'll have famine in that many turns.
255 But that's handled down below. */
256 fc_snprintf(buf
, sizeof(buf
),
257 PL_("%d turn", "%d turns", abs(granaryturns
)),
262 /* We used to mark cities with a granary with a "*" here. */
263 fc_snprintf(retbuf
, n
, _("Granary: %3d/%-3d\n"
265 foodstock
, foodbox
, buf
);
268 /****************************************************************
270 *****************************************************************/
271 static void get_contents_of_production(struct city_dialog
*pdialog
,
283 pcity
=pdialog
->pcity
;
284 foodprod
=pcity
->prod
[O_FOOD
];
285 foodsurplus
= pcity
->surplus
[O_FOOD
];
286 shieldprod
=pcity
->prod
[O_SHIELD
] + pcity
->waste
[O_SHIELD
];
287 shieldsurplus
= pcity
->surplus
[O_SHIELD
];
288 tradeprod
= pcity
->surplus
[O_TRADE
] + pcity
->waste
[O_TRADE
];
289 tradesurplus
= pcity
->surplus
[O_TRADE
];
292 fc_snprintf(retbuf
, n
,
293 _("Food: %3d (%+-4d)\n"
294 "Prod: %3d (%+-4d)\n"
295 "Trade: %3d (%+-4d)"),
296 foodprod
, foodsurplus
,
297 shieldprod
, shieldsurplus
,
298 tradeprod
, tradesurplus
);
301 /****************************************************************
303 *****************************************************************/
304 static void get_contents_of_output(struct city_dialog
*pdialog
,
314 pcity
=pdialog
->pcity
;
315 goldtotal
=pcity
->prod
[O_GOLD
];
316 goldsurplus
= pcity
->surplus
[O_GOLD
];
317 luxtotal
=pcity
->prod
[O_LUXURY
];
318 scitotal
=pcity
->prod
[O_SCIENCE
];
321 fc_snprintf(retbuf
, n
,
322 _("Gold: %3d (%+-4d)\n"
325 goldtotal
, goldsurplus
,
330 /****************************************************************
332 *****************************************************************/
333 static void get_contents_of_progress(struct city_dialog
*pdialog
,
336 get_city_dialog_production(pdialog
? pdialog
->pcity
: NULL
, retbuf
, n
);
339 /****************************************************************
341 *****************************************************************/
342 static void get_contents_of_worklist(struct city_dialog
*pdialog
,
345 struct city
*pcity
= pdialog
? pdialog
->pcity
: NULL
;
347 if (pcity
&& worklist_is_empty(&pcity
->worklist
)) {
348 fc_strlcpy(retbuf
, _("(is empty)"), n
);
350 fc_strlcpy(retbuf
, _("(in prog.)"), n
);
354 /****************************************************************
356 *****************************************************************/
357 struct city_dialog
*get_city_dialog(struct city
*pcity
)
359 if (!dialog_list_has_been_initialised
) {
360 dialog_list
= dialog_list_new();
361 dialog_list_has_been_initialised
= TRUE
;
364 dialog_list_iterate(dialog_list
, pdialog
) {
365 if (pdialog
->pcity
== pcity
) {
368 } dialog_list_iterate_end
;
373 /****************************************************************
375 *****************************************************************/
376 bool city_dialog_is_open(struct city
*pcity
)
378 return get_city_dialog(pcity
) != NULL
;
381 /****************************************************************
383 *****************************************************************/
384 void real_city_dialog_refresh(struct city
*pcity
)
386 struct city_dialog
*pdialog
;
388 if((pdialog
=get_city_dialog(pcity
))) {
389 struct canvas store
= {XtWindow(pdialog
->map_canvas
)};
391 city_dialog_update_improvement_list(pdialog
);
392 city_dialog_update_title(pdialog
);
393 city_dialog_update_supported_units(pdialog
, 0);
394 city_dialog_update_present_units(pdialog
, 0);
395 city_dialog_update_citizens(pdialog
);
396 city_dialog_redraw_map(pdialog
->pcity
, &store
);
397 city_dialog_update_production(pdialog
);
398 city_dialog_update_output(pdialog
);
399 city_dialog_update_building(pdialog
);
400 city_dialog_update_storage(pdialog
);
401 city_dialog_update_pollution(pdialog
);
403 XtSetSensitive(pdialog
->trade_command
,
404 city_num_trade_routes(pcity
)?True
:False
);
405 XtSetSensitive(pdialog
->activate_command
,
406 unit_list_size(pcity
->tile
->units
)
408 XtSetSensitive(pdialog
->show_units_command
,
409 unit_list_size(pcity
->tile
->units
)
411 XtSetSensitive(pdialog
->cma_command
, True
);
412 XtSetSensitive(pdialog
->cityopt_command
, True
);
415 if (NULL
== client
.conn
.playing
416 || city_owner(pcity
) == client
.conn
.playing
) {
417 city_report_dialog_update_city(pcity
);
418 economy_report_dialog_update();
421 /* Set the buttons we do not want live while a Diplomat investigates */
422 XtSetSensitive(pdialog
->buy_command
, FALSE
);
423 XtSetSensitive(pdialog
->change_command
, FALSE
);
424 XtSetSensitive(pdialog
->worklist_command
, FALSE
);
425 XtSetSensitive(pdialog
->sell_command
, FALSE
);
426 XtSetSensitive(pdialog
->rename_command
, FALSE
);
427 XtSetSensitive(pdialog
->activate_command
, FALSE
);
428 XtSetSensitive(pdialog
->show_units_command
, FALSE
);
429 XtSetSensitive(pdialog
->cma_command
, FALSE
);
430 XtSetSensitive(pdialog
->cityopt_command
, FALSE
);
435 /**************************************************************************
436 Updates supported and present units views in city dialogs for given unit
437 **************************************************************************/
438 void refresh_unit_city_dialogs(struct unit
*punit
)
440 struct city
*pcity_sup
, *pcity_pre
;
441 struct city_dialog
*pdialog
;
443 pcity_sup
= player_city_by_number(client_player(), punit
->homecity
);
444 pcity_pre
=tile_city(unit_tile(punit
));
446 if(pcity_sup
&& (pdialog
=get_city_dialog(pcity_sup
)))
447 city_dialog_update_supported_units(pdialog
, 0);
449 if(pcity_pre
&& (pdialog
=get_city_dialog(pcity_pre
)))
450 city_dialog_update_present_units(pdialog
, 0);
453 /****************************************************************
454 popup the dialog 10% inside the main-window
455 *****************************************************************/
456 void real_city_dialog_popup(struct city
*pcity
)
458 struct city_dialog
*pdialog
;
460 if(!(pdialog
=get_city_dialog(pcity
)))
461 pdialog
=create_city_dialog(pcity
);
463 xaw_set_relative_position(toplevel
, pdialog
->shell
, 10, 10);
464 XtPopup(pdialog
->shell
, XtGrabNone
);
467 /****************************************************************
469 *****************************************************************/
470 void popdown_city_dialog(struct city
*pcity
)
472 struct city_dialog
*pdialog
;
474 if((pdialog
=get_city_dialog(pcity
)))
475 close_city_dialog(pdialog
);
478 /****************************************************************
480 *****************************************************************/
481 void popdown_all_city_dialogs(void)
483 if(!dialog_list_has_been_initialised
) {
486 while (dialog_list_size(dialog_list
) > 0) {
487 close_city_dialog(dialog_list_get(dialog_list
, 0));
489 popdown_cityopt_dialog();
490 popdown_cma_dialog();
494 /****************************************************************
496 *****************************************************************/
497 static void city_map_canvas_expose(Widget w
, XEvent
*event
, Region exposed
,
500 struct city_dialog
*pdialog
= client_data
;
501 struct canvas store
= {XtWindow(pdialog
->map_canvas
)};
503 city_dialog_redraw_map(pdialog
->pcity
, &store
);
507 /****************************************************************
509 *****************************************************************/
511 #define LAYOUT_DEBUG 0
513 struct city_dialog
*create_city_dialog(struct city
*pcity
)
515 char *dummy_improvement_list
[]={
516 "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
529 struct city_dialog
*pdialog
;
531 Widget first_citizen
, first_support
, first_present
;
532 XtWidgetGeometry geom
;
533 Dimension widthTotal
;
534 Dimension widthCitizen
, borderCitizen
, internalCitizen
, spaceCitizen
;
535 Dimension widthUnit
, borderUnit
, internalUnit
, spaceUnit
;
536 Dimension widthNext
, borderNext
, internalNext
, spaceNext
;
537 Dimension widthPrev
, borderPrev
, internalPrev
, spacePrev
;
539 enum citizen_category c
= CITIZEN_SPECIALIST
+ DEFAULT_SPECIALIST
;
541 if (tileset_tile_height(tileset
) < 45) {
542 dummy_improvement_list
[5] = 0;
545 if (gui_options
.concise_city_production
) {
546 dummy_improvement_list
[0] = "XXXXXXXXXXXXXXXXXXXXXXXXXXXX";
549 pdialog
= fc_malloc(sizeof(struct city_dialog
));
550 pdialog
->pcity
= pcity
;
551 pdialog
->support_unit_base
= 0;
552 pdialog
->present_unit_base
= 0;
553 pdialog
->worklist_shell
= NULL
;
556 XtVaCreatePopupShell(city_name_get(pcity
),
557 topLevelShellWidgetClass
,
559 XtNallowShellResize
, True
,
563 XtVaCreateManagedWidget("citymainform",
568 pdialog
->cityname_label
=
569 XtVaCreateManagedWidget("citynamelabel",
576 XtVaCreateManagedWidget("citizenlabels",
580 pdialog
->cityname_label
,
582 get_citizen_pixmap(c
, 0, pcity
),
587 XtVaCreateManagedWidget("citysubform",
591 (XtArgVal
)first_citizen
,
596 XtVaCreateManagedWidget("cityleftform",
601 get_contents_of_production(NULL
, lblbuf
, sizeof(lblbuf
));
602 pdialog
->production_label
=
603 XtVaCreateManagedWidget("cityprodlabel",
609 get_contents_of_output(NULL
, lblbuf
, sizeof(lblbuf
));
610 pdialog
->output_label
=
611 XtVaCreateManagedWidget("cityoutputlabel",
616 (XtArgVal
)pdialog
->production_label
,
619 get_contents_of_storage(NULL
, lblbuf
, sizeof(lblbuf
));
620 pdialog
->storage_label
=
621 XtVaCreateManagedWidget("citystoragelabel",
626 (XtArgVal
)pdialog
->output_label
,
629 get_contents_of_pollution(NULL
, lblbuf
, sizeof(lblbuf
));
630 pdialog
->pollution_label
=
631 XtVaCreateManagedWidget("citypollutionlabel",
636 (XtArgVal
)pdialog
->storage_label
,
641 XtVaCreateManagedWidget("citymapcanvas",
642 xfwfcanvasWidgetClass
,
644 "exposeProc", (XtArgVal
)city_map_canvas_expose
,
645 "exposeProcData", (XtArgVal
)pdialog
,
646 XtNfromHoriz
, (XtArgVal
)pdialog
->left_form
,
647 XtNwidth
, get_citydlg_canvas_width(),
648 XtNheight
, get_citydlg_canvas_height(),
652 pdialog
->building_label
=
653 XtVaCreateManagedWidget("citybuildinglabel",
657 (XtArgVal
)pdialog
->map_canvas
,
659 gui_options
.concise_city_production
660 ? "XXXXXXXXXXXXXXXXXXXXXXXXXXXX"
661 : "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
664 get_contents_of_progress(NULL
, lblbuf
, sizeof(lblbuf
));
665 pdialog
->progress_label
=
666 XtVaCreateManagedWidget("cityprogresslabel",
670 (XtArgVal
)pdialog
->map_canvas
,
672 pdialog
->building_label
,
676 pdialog
->buy_command
=
677 I_L(XtVaCreateManagedWidget("citybuycommand",
681 pdialog
->building_label
,
683 pdialog
->progress_label
,
686 pdialog
->change_command
=
687 I_L(XtVaCreateManagedWidget("citychangecommand",
691 pdialog
->building_label
,
693 pdialog
->buy_command
,
696 pdialog
->improvement_viewport
=
697 XtVaCreateManagedWidget("cityimprovview",
701 (XtArgVal
)pdialog
->map_canvas
,
703 pdialog
->change_command
,
706 pdialog
->improvement_list
=
707 XtVaCreateManagedWidget("cityimprovlist",
709 pdialog
->improvement_viewport
,
713 (XtArgVal
)dummy_improvement_list
,
714 XtNverticalList
, False
,
717 pdialog
->sell_command
=
718 I_L(XtVaCreateManagedWidget("citysellcommand",
722 pdialog
->improvement_viewport
,
724 (XtArgVal
)pdialog
->map_canvas
,
727 pdialog
->worklist_command
=
728 I_L(XtVaCreateManagedWidget("cityworklistcommand",
732 pdialog
->improvement_viewport
,
734 pdialog
->sell_command
,
737 get_contents_of_worklist(NULL
, lblbuf
, sizeof(lblbuf
));
738 pdialog
->worklist_label
=
739 XtVaCreateManagedWidget("cityworklistlabel",
743 pdialog
->improvement_viewport
,
745 pdialog
->worklist_command
,
750 pdialog
->support_unit_label
=
751 I_L(XtVaCreateManagedWidget("supportunitlabel",
759 XtVaCreateManagedWidget("supportunitcanvas",
762 XtNfromVert
, pdialog
->support_unit_label
,
763 XtNwidth
, tileset_full_tile_width(tileset
),
764 XtNheight
, 3 * tileset_tile_height(tileset
) / 2,
767 pdialog
->present_unit_label
=
768 I_L(XtVaCreateManagedWidget("presentunitlabel",
776 XtVaCreateManagedWidget("presentunitcanvas",
779 XtNfromVert
, pdialog
->present_unit_label
,
780 XtNwidth
, tileset_full_tile_width(tileset
),
781 XtNheight
, tileset_full_tile_height(tileset
),
785 pdialog
->support_unit_next_command
=
786 XtVaCreateManagedWidget("supportunitnextcommand",
790 pdialog
->support_unit_prev_command
=
791 XtVaCreateManagedWidget("supportunitprevcommand",
796 pdialog
->present_unit_next_command
=
797 XtVaCreateManagedWidget("presentunitnextcommand",
801 pdialog
->present_unit_prev_command
=
802 XtVaCreateManagedWidget("presentunitprevcommand",
808 pdialog
->close_command
=
809 I_L(XtVaCreateManagedWidget("cityclosecommand",
812 XtNfromVert
, first_present
,
815 pdialog
->rename_command
=
816 I_L(XtVaCreateManagedWidget("cityrenamecommand",
819 XtNfromVert
, first_present
,
820 XtNfromHoriz
, pdialog
->close_command
,
823 pdialog
->trade_command
=
824 I_L(XtVaCreateManagedWidget("citytradecommand",
827 XtNfromVert
, first_present
,
828 XtNfromHoriz
, pdialog
->rename_command
,
831 pdialog
->activate_command
=
832 I_L(XtVaCreateManagedWidget("cityactivatecommand",
835 XtNfromVert
, first_present
,
836 XtNfromHoriz
, pdialog
->trade_command
,
839 pdialog
->show_units_command
=
840 I_L(XtVaCreateManagedWidget("cityshowunitscommand",
843 XtNfromVert
, first_present
,
844 XtNfromHoriz
, pdialog
->activate_command
,
847 pdialog
->cma_command
=
848 I_L(XtVaCreateManagedWidget("cmacommand",
851 XtNfromVert
, first_present
,
852 XtNfromHoriz
, pdialog
->show_units_command
,
855 pdialog
->cityopt_command
=
856 I_L(XtVaCreateManagedWidget("cityoptionscommand",
859 XtNfromVert
, first_present
,
860 XtNfromHoriz
, pdialog
->cma_command
,
864 XtRealizeWidget(pdialog
->shell
);
865 XtQueryGeometry (pdialog
->sub_form
, NULL
, &geom
);
866 widthTotal
=geom
.width
;
868 XtQueryGeometry (first_citizen
, NULL
, &geom
);
869 widthCitizen
=geom
.width
;
870 borderCitizen
=geom
.border_width
;
871 XtVaGetValues(first_citizen
,
872 XtNinternalWidth
, &internalCitizen
,
873 XtNhorizDistance
, &spaceCitizen
,
875 XtQueryGeometry (first_support
, NULL
, &geom
);
876 widthUnit
=geom
.width
;
877 borderUnit
=geom
.border_width
;
878 XtVaGetValues(first_support
,
879 XtNinternalWidth
, &internalUnit
,
880 XtNhorizDistance
, &spaceUnit
,
882 XtQueryGeometry (pdialog
->support_unit_next_command
, NULL
, &geom
);
883 widthNext
=geom
.width
;
884 borderNext
=geom
.border_width
;
885 XtVaGetValues(pdialog
->support_unit_next_command
,
886 XtNinternalWidth
, &internalNext
,
887 XtNhorizDistance
, &spaceNext
,
889 XtQueryGeometry (pdialog
->support_unit_prev_command
, NULL
, &geom
);
890 widthPrev
=geom
.width
;
891 borderPrev
=geom
.border_width
;
892 XtVaGetValues(pdialog
->support_unit_prev_command
,
893 XtNinternalWidth
, &internalPrev
,
894 XtNhorizDistance
, &spacePrev
,
896 #if LAYOUT_DEBUG >= 3
900 "C: wbis: %d %d %d %d\n"
901 "U: wbis: %d %d %d %d\n"
902 "N: wbis: %d %d %d %d\n"
903 "P: wbis: %d %d %d %d\n"
906 widthCitizen
, borderCitizen
, internalCitizen
, spaceCitizen
,
907 widthUnit
, borderUnit
, internalUnit
, spaceUnit
,
908 widthNext
, borderNext
, internalNext
, spaceNext
,
909 widthPrev
, borderPrev
, internalPrev
, spacePrev
912 itemWidth
=widthCitizen
+2*borderCitizen
+2*internalCitizen
+spaceCitizen
;
914 pdialog
->num_citizens_shown
=widthTotal
/itemWidth
;
915 if (pdialog
->num_citizens_shown
<MIN_NUM_CITIZENS
)
916 pdialog
->num_citizens_shown
=MIN_NUM_CITIZENS
;
917 else if (pdialog
->num_citizens_shown
>MAX_NUM_CITIZENS
)
918 pdialog
->num_citizens_shown
=MAX_NUM_CITIZENS
;
920 pdialog
->num_citizens_shown
=MIN_NUM_CITIZENS
;
922 #if LAYOUT_DEBUG >= 2
925 "C: wT iW nC: %d %d %d\n"
929 pdialog
->num_citizens_shown
932 if (widthNext
<widthPrev
) widthNext
=widthPrev
;
933 if (borderNext
<borderPrev
) borderNext
=borderPrev
;
934 if (internalNext
<internalPrev
) internalNext
=internalPrev
;
935 if (spaceNext
<spacePrev
) spaceNext
=spacePrev
;
936 widthTotal
-=(widthNext
+2*borderNext
+2*internalNext
+spaceNext
);
937 itemWidth
=widthUnit
+2*borderUnit
+2*internalUnit
+spaceUnit
;
939 pdialog
->num_units_shown
=widthTotal
/itemWidth
;
940 if (pdialog
->num_units_shown
<MIN_NUM_UNITS
)
941 pdialog
->num_units_shown
=MIN_NUM_UNITS
;
942 else if (pdialog
->num_units_shown
>MAX_NUM_UNITS
)
943 pdialog
->num_units_shown
=MAX_NUM_UNITS
;
945 pdialog
->num_units_shown
=MIN_NUM_UNITS
;
947 #if LAYOUT_DEBUG >= 2
950 "U: wT iW nU: %d %d %d\n"
954 pdialog
->num_units_shown
958 pdialog
->num_citizens_shown
=DEFAULT_NUM_CITIZENS
;
959 pdialog
->num_units_shown
=DEFAULT_NUM_UNITS
;
960 if (tileset_tile_height(tileset
)<45) {
961 pdialog
->num_citizens_shown
-=5;
962 pdialog
->num_units_shown
+=3;
965 #if LAYOUT_DEBUG >= 1
970 pdialog
->num_citizens_shown
, pdialog
->num_units_shown
974 pdialog
->citizen_labels
=
975 fc_malloc(pdialog
->num_citizens_shown
* sizeof(Widget
));
977 pdialog
->support_unit_pixcomms
=
978 fc_malloc(pdialog
->num_units_shown
* sizeof(Widget
));
979 pdialog
->present_unit_pixcomms
=
980 fc_malloc(pdialog
->num_units_shown
* sizeof(Widget
));
983 pdialog
->citizen_labels
[0]=first_citizen
;
984 for(i
=1; i
<pdialog
->num_citizens_shown
; i
++)
985 pdialog
->citizen_labels
[i
]=
986 XtVaCreateManagedWidget("citizenlabels",
989 XtNfromVert
, pdialog
->cityname_label
,
991 (XtArgVal
)pdialog
->citizen_labels
[i
-1],
993 get_citizen_pixmap(c
, 0, pcity
),
997 pdialog
->support_unit_pixcomms
[0]=first_support
;
998 for(i
=1; i
<pdialog
->num_units_shown
; i
++) {
999 pdialog
->support_unit_pixcomms
[i
]=
1000 XtVaCreateManagedWidget("supportunitcanvas",
1003 XtNfromVert
, pdialog
->support_unit_label
,
1005 (XtArgVal
)pdialog
->support_unit_pixcomms
[i
-1],
1006 XtNwidth
, tileset_full_tile_width(tileset
),
1007 XtNheight
, 3 * tileset_tile_height(tileset
) / 2,
1011 relative
=pdialog
->support_unit_pixcomms
[pdialog
->num_units_shown
-1];
1012 XtVaSetValues(pdialog
->support_unit_next_command
,
1013 XtNfromVert
, pdialog
->support_unit_label
,
1014 XtNfromHoriz
, (XtArgVal
)relative
,
1016 XtVaSetValues(pdialog
->support_unit_prev_command
,
1017 XtNfromVert
, pdialog
->support_unit_next_command
,
1018 XtNfromHoriz
, (XtArgVal
)relative
,
1021 pdialog
->present_unit_pixcomms
[0]=first_present
;
1022 for(i
=1; i
<pdialog
->num_units_shown
; i
++) {
1023 pdialog
->present_unit_pixcomms
[i
]=
1024 XtVaCreateManagedWidget("presentunitcanvas",
1027 XtNfromVert
, pdialog
->present_unit_label
,
1029 (XtArgVal
)pdialog
->support_unit_pixcomms
[i
-1],
1030 XtNwidth
, tileset_full_tile_width(tileset
),
1031 XtNheight
, tileset_full_tile_height(tileset
),
1035 relative
=pdialog
->present_unit_pixcomms
[pdialog
->num_units_shown
-1];
1036 XtVaSetValues(pdialog
->present_unit_next_command
,
1037 XtNfromVert
, pdialog
->present_unit_label
,
1038 XtNfromHoriz
, (XtArgVal
)relative
,
1040 XtVaSetValues(pdialog
->present_unit_prev_command
,
1041 XtNfromVert
, pdialog
->present_unit_next_command
,
1042 XtNfromHoriz
, (XtArgVal
)relative
,
1045 /* FIXME: this ignores the mask. */
1046 XtVaSetValues(pdialog
->shell
, XtNiconPixmap
,
1047 get_icon_sprite(tileset
, ICON_CITYDLG
), NULL
);
1050 XtAddCallback(pdialog
->sell_command
, XtNcallback
, sell_callback
,
1051 (XtPointer
)pdialog
);
1053 XtAddCallback(pdialog
->buy_command
, XtNcallback
, buy_callback
,
1054 (XtPointer
)pdialog
);
1056 XtAddCallback(pdialog
->change_command
, XtNcallback
, change_callback
,
1057 (XtPointer
)pdialog
);
1059 XtAddCallback(pdialog
->worklist_command
, XtNcallback
, worklist_callback
,
1060 (XtPointer
)pdialog
);
1062 XtAddCallback(pdialog
->close_command
, XtNcallback
, close_callback
,
1063 (XtPointer
)pdialog
);
1065 XtAddCallback(pdialog
->rename_command
, XtNcallback
, rename_callback
,
1066 (XtPointer
)pdialog
);
1068 XtAddCallback(pdialog
->trade_command
, XtNcallback
, trade_callback
,
1069 (XtPointer
)pdialog
);
1071 XtAddCallback(pdialog
->activate_command
, XtNcallback
, activate_callback
,
1072 (XtPointer
)pdialog
);
1074 XtAddCallback(pdialog
->show_units_command
, XtNcallback
, show_units_callback
,
1075 (XtPointer
)pdialog
);
1077 XtAddCallback(pdialog
->support_unit_next_command
, XtNcallback
,
1078 units_next_prev_callback
, (XtPointer
)pdialog
);
1079 XtAddCallback(pdialog
->support_unit_prev_command
, XtNcallback
,
1080 units_next_prev_callback
, (XtPointer
)pdialog
);
1081 XtAddCallback(pdialog
->present_unit_next_command
, XtNcallback
,
1082 units_next_prev_callback
, (XtPointer
)pdialog
);
1083 XtAddCallback(pdialog
->present_unit_prev_command
, XtNcallback
,
1084 units_next_prev_callback
, (XtPointer
)pdialog
);
1086 XtAddCallback(pdialog
->cityopt_command
, XtNcallback
, cityopt_callback
,
1087 (XtPointer
)pdialog
);
1089 XtAddCallback(pdialog
->cma_command
, XtNcallback
, cma_callback
,
1090 (XtPointer
)pdialog
);
1092 dialog_list_prepend(dialog_list
, pdialog
);
1094 for(i
=0; i
<B_LAST
+1; i
++)
1095 pdialog
->improvlist_names_ptrs
[i
]=0;
1097 XtRealizeWidget(pdialog
->shell
);
1099 real_city_dialog_refresh(pdialog
->pcity
);
1102 XtSetSensitive(toplevel, FALSE);
1104 pdialog->is_modal=make_modal;
1107 XSetWMProtocols(display
, XtWindow(pdialog
->shell
), &wm_delete_window
, 1);
1108 XtOverrideTranslations(pdialog
->shell
,
1109 XtParseTranslationTable ("<Message>WM_PROTOCOLS: msg-close-city()"));
1111 XtSetKeyboardFocus(pdialog
->shell
, pdialog
->close_command
);
1117 /****************************************************************
1119 *****************************************************************/
1120 void activate_callback(Widget w
, XtPointer client_data
,
1121 XtPointer call_data
)
1123 struct city_dialog
*pdialog
= (struct city_dialog
*)client_data
;
1125 activate_all_units(pdialog
->pcity
->tile
);
1129 /****************************************************************
1131 *****************************************************************/
1132 void show_units_callback(Widget w
, XtPointer client_data
,
1133 XtPointer call_data
)
1135 struct city_dialog
*pdialog
= (struct city_dialog
*)client_data
;
1136 struct tile
*ptile
= pdialog
->pcity
->tile
;
1138 if( unit_list_size(ptile
->units
) )
1139 unit_select_dialog_popup(ptile
);
1143 /****************************************************************
1145 *****************************************************************/
1146 void units_next_prev_callback(Widget w
, XtPointer client_data
,
1147 XtPointer call_data
)
1149 struct city_dialog
*pdialog
= (struct city_dialog
*)client_data
;
1151 if (w
==pdialog
->support_unit_next_command
) {
1152 (pdialog
->support_unit_base
)++;
1153 city_dialog_update_supported_units(pdialog
, 0);
1154 } else if (w
==pdialog
->support_unit_prev_command
) {
1155 (pdialog
->support_unit_base
)--;
1156 city_dialog_update_supported_units(pdialog
, 0);
1157 } else if (w
==pdialog
->present_unit_next_command
) {
1158 (pdialog
->present_unit_base
)++;
1159 city_dialog_update_present_units(pdialog
, 0);
1160 } else if (w
==pdialog
->present_unit_prev_command
) {
1161 (pdialog
->present_unit_base
)--;
1162 city_dialog_update_present_units(pdialog
, 0);
1168 /****************************************************************
1170 *****************************************************************/
1171 static void present_units_ok_callback(Widget w
, XtPointer client_data
,
1172 XtPointer call_data
)
1174 destroy_message_dialog(w
);
1179 /****************************************************************
1181 *****************************************************************/
1182 static void present_units_activate_callback(Widget w
, XtPointer client_data
,
1183 XtPointer call_data
)
1185 struct unit
*punit
=
1186 player_unit_by_number(client_player(), (size_t) client_data
);
1188 if (NULL
!= punit
) {
1189 struct city
*pcity
= tile_city(unit_tile(punit
));
1191 unit_focus_set(punit
);
1192 if (NULL
!= pcity
) {
1193 struct city_dialog
*pdialog
= get_city_dialog(pcity
);
1195 if (NULL
!= pdialog
) {
1196 city_dialog_update_present_units(pdialog
, 0);
1201 destroy_message_dialog(w
);
1205 /****************************************************************
1207 *****************************************************************/
1208 static void supported_units_activate_callback(Widget w
, XtPointer client_data
,
1209 XtPointer call_data
)
1211 struct unit
*punit
=
1212 player_unit_by_number(client_player(), (size_t) client_data
);
1214 if (NULL
!= punit
) {
1215 struct city
*pcity
= tile_city(unit_tile(punit
));
1217 unit_focus_set(punit
);
1218 if (NULL
!= pcity
) {
1219 struct city_dialog
*pdialog
= get_city_dialog(pcity
);
1221 if (NULL
!= pdialog
) {
1222 city_dialog_update_supported_units(pdialog
, 0);
1227 destroy_message_dialog(w
);
1231 /****************************************************************
1233 *****************************************************************/
1234 static void present_units_activate_close_callback(Widget w
,
1235 XtPointer client_data
,
1236 XtPointer call_data
)
1238 struct unit
*punit
=
1239 player_unit_by_number(client_player(), (size_t) client_data
);
1241 destroy_message_dialog(w
);
1243 if (NULL
!= punit
) {
1244 struct city
*pcity
= tile_city(unit_tile(punit
));
1246 unit_focus_set(punit
);
1247 if (NULL
!= pcity
) {
1248 struct city_dialog
*pdialog
= get_city_dialog(pcity
);
1250 if (NULL
!= pdialog
) {
1251 close_city_dialog(pdialog
);
1257 /****************************************************************
1259 *****************************************************************/
1260 static void supported_units_activate_close_callback(Widget w
,
1261 XtPointer client_data
,
1262 XtPointer call_data
)
1264 struct unit
*punit
=
1265 player_unit_by_number(client_player(), (size_t) client_data
);
1267 destroy_message_dialog(w
);
1269 if (NULL
!= punit
) {
1270 struct city
*pcity
=
1271 player_city_by_number(client_player(), punit
->homecity
);
1273 unit_focus_set(punit
);
1274 if (NULL
!= pcity
) {
1275 struct city_dialog
*pdialog
= get_city_dialog(pcity
);
1277 if (NULL
!= pdialog
) {
1278 close_city_dialog(pdialog
);
1285 /****************************************************************
1287 *****************************************************************/
1288 static void present_units_sentry_callback(Widget w
, XtPointer client_data
,
1289 XtPointer call_data
)
1291 struct unit
*punit
=
1292 player_unit_by_number(client_player(), (size_t) client_data
);
1294 if (NULL
!= punit
) {
1295 request_unit_sentry(punit
);
1298 destroy_message_dialog(w
);
1302 /****************************************************************
1304 *****************************************************************/
1305 static void present_units_fortify_callback(Widget w
, XtPointer client_data
,
1306 XtPointer call_data
)
1308 struct unit
*punit
=
1309 player_unit_by_number(client_player(), (size_t) client_data
);
1311 if (NULL
!= punit
) {
1312 request_unit_fortify(punit
);
1315 destroy_message_dialog(w
);
1319 /****************************************************************
1321 *****************************************************************/
1322 static void present_units_homecity_callback(Widget w
, XtPointer client_data
,
1323 XtPointer call_data
)
1325 struct unit
*punit
=
1326 player_unit_by_number(client_player(), (size_t) client_data
);
1328 if (NULL
!= punit
) {
1329 request_unit_change_homecity(punit
);
1332 destroy_message_dialog(w
);
1336 /****************************************************************
1338 *****************************************************************/
1339 static void present_units_cancel_callback(Widget w
, XtPointer client_data
,
1340 XtPointer call_data
)
1342 destroy_message_dialog(w
);
1346 /****************************************************************
1348 *****************************************************************/
1349 void present_units_callback(Widget w
, XtPointer client_data
,
1350 XtPointer call_data
)
1353 struct city_dialog
*pdialog
;
1355 XEvent
*e
= (XEvent
*)call_data
;
1356 struct unit
*punit
=
1357 player_unit_by_number(client_player(), (size_t) client_data
);
1360 || (can_conn_edit(&client
.conn
)
1361 && NULL
== client
.conn
.playing
1362 && (punit
= game_unit_by_number((size_t) client_data
))))
1363 && (pcity
= tile_city(unit_tile(punit
)))
1364 && (pdialog
= get_city_dialog(pcity
))) {
1366 if(e
->type
==ButtonRelease
&& e
->xbutton
.button
==Button2
) {
1367 unit_focus_set(punit
);
1368 close_city_dialog(pdialog
);
1371 if(e
->type
==ButtonRelease
&& e
->xbutton
.button
==Button3
) {
1372 unit_focus_set(punit
);
1376 wd
=popup_message_dialog(pdialog
->shell
,
1377 "presentunitsdialog",
1378 unit_description(punit
),
1379 present_units_activate_callback
, punit
->id
, 1,
1380 present_units_activate_close_callback
, punit
->id
, 1,
1381 present_units_sentry_callback
, punit
->id
, 1,
1382 present_units_fortify_callback
, punit
->id
, 1,
1383 disband_callback
, punit
->id
, 1,
1384 present_units_homecity_callback
, punit
->id
, 1,
1385 upgrade_callback
, punit
->id
, 1,
1386 present_units_cancel_callback
, 0, 0,
1389 if (punit
->activity
== ACTIVITY_SENTRY
1390 || !can_unit_do_activity(punit
, ACTIVITY_SENTRY
)) {
1391 XtSetSensitive(XtNameToWidget(wd
, "*button2"), FALSE
);
1393 if (punit
->activity
== ACTIVITY_FORTIFYING
1394 || !can_unit_do_activity(punit
, ACTIVITY_FORTIFYING
)) {
1395 XtSetSensitive(XtNameToWidget(wd
, "*button3"), FALSE
);
1397 if (unit_has_type_flag(punit
, UTYF_UNDISBANDABLE
)) {
1398 XtSetSensitive(XtNameToWidget(wd
, "*button4"), FALSE
);
1400 if (punit
->homecity
== pcity
->id
) {
1401 XtSetSensitive(XtNameToWidget(wd
, "*button5"), FALSE
);
1403 if (NULL
== client
.conn
.playing
1404 || (NULL
== can_upgrade_unittype(client
.conn
.playing
,
1405 unit_type_get(punit
)))) {
1406 XtSetSensitive(XtNameToWidget(wd
, "*button6"), FALSE
);
1411 /****************************************************************
1413 *****************************************************************/
1414 static void rename_city_callback(Widget w
, XtPointer client_data
,
1415 XtPointer call_data
)
1417 struct city_dialog
*pdialog
= client_data
;
1420 city_rename(pdialog
->pcity
, input_dialog_get_input(w
));
1422 input_dialog_destroy(w
);
1429 /****************************************************************
1431 *****************************************************************/
1432 void rename_callback(Widget w
, XtPointer client_data
, XtPointer call_data
)
1434 struct city_dialog
*pdialog
;
1436 pdialog
=(struct city_dialog
*)client_data
;
1438 input_dialog_create(pdialog
->shell
,
1440 _("What should we rename the city to?"),
1441 city_name_get(pdialog
->pcity
),
1442 rename_city_callback
, (XtPointer
)pdialog
,
1443 rename_city_callback
, (XtPointer
)0);
1446 /****************************************************************
1448 *****************************************************************/
1449 static void trade_message_dialog_callback(Widget w
, XtPointer client_data
,
1450 XtPointer call_data
)
1452 destroy_message_dialog(w
);
1455 /****************************************************************
1457 *****************************************************************/
1458 void trade_callback(Widget w
, XtPointer client_data
, XtPointer call_data
)
1462 char buf
[512], *bptr
=buf
;
1463 int nleft
= sizeof(buf
);
1464 struct city_dialog
*pdialog
;
1466 pdialog
= (struct city_dialog
*)client_data
;
1468 fc_snprintf(buf
, sizeof(buf
),
1469 _("These trade routes have been established with %s:\n"),
1470 city_name_get(pdialog
->pcity
));
1471 bptr
= end_of_strn(bptr
, &nleft
);
1473 for (i
= 0; i
< MAX_TRADE_ROUTES
; i
++)
1474 if(pdialog
->pcity
->trade
[i
]) {
1477 total
+=pdialog
->pcity
->trade_value
[i
];
1478 if ((pcity
= game_city_by_number(pdialog
->pcity
->trade
[i
]))) {
1479 fc_snprintf(bptr
, nleft
, _("%32s: %2d Trade/Year\n"),
1480 city_name_get(pcity
), pdialog
->pcity
->trade_value
[i
]);
1481 bptr
= end_of_strn(bptr
, &nleft
);
1483 fc_snprintf(bptr
, nleft
, _("%32s: %2d Trade/Year\n"), _("Unknown"),
1484 pdialog
->pcity
->trade_value
[i
]);
1485 bptr
= end_of_strn(bptr
, &nleft
);
1489 fc_strlcpy(bptr
, _("No trade routes exist.\n"), nleft
);
1491 fc_snprintf(bptr
, nleft
, _("\nTotal trade %d Trade/Year\n"), total
);
1494 popup_message_dialog(pdialog
->shell
,
1497 trade_message_dialog_callback
, 0, 0,
1502 /****************************************************************
1504 *****************************************************************/
1505 void city_dialog_update_pollution(struct city_dialog
*pdialog
)
1509 get_contents_of_pollution(pdialog
, buf
, sizeof(buf
));
1510 xaw_set_label(pdialog
->pollution_label
, buf
);
1513 /****************************************************************
1515 *****************************************************************/
1516 void city_dialog_update_storage(struct city_dialog
*pdialog
)
1520 get_contents_of_storage(pdialog
, buf
, sizeof(buf
));
1521 xaw_set_label(pdialog
->storage_label
, buf
);
1524 /****************************************************************
1526 *****************************************************************/
1527 void city_dialog_update_building(struct city_dialog
*pdialog
)
1530 struct city
*pcity
=pdialog
->pcity
;
1532 XtSetSensitive(pdialog
->buy_command
, city_can_buy(pcity
));
1533 /* FIXME: Should not pass NULL as improvement
1534 * to test_player_sell_building_now(). It skips many tests. */
1535 XtSetSensitive(pdialog
->sell_command
,
1536 test_player_sell_building_now(client
.conn
.playing
,
1537 pcity
, NULL
) == TR_SUCCESS
);
1539 xaw_set_label(pdialog
->building_label
,
1540 city_production_name_translation(pcity
));
1542 get_contents_of_progress(pdialog
, buf
, sizeof(buf
));
1543 xaw_set_label(pdialog
->progress_label
, buf
);
1545 get_contents_of_worklist(pdialog
, buf
, sizeof(buf
));
1546 xaw_set_label(pdialog
->worklist_label
, buf
);
1549 /****************************************************************
1551 *****************************************************************/
1552 void city_dialog_update_production(struct city_dialog
*pdialog
)
1556 get_contents_of_production(pdialog
, buf
, sizeof(buf
));
1557 xaw_set_label(pdialog
->production_label
, buf
);
1560 /****************************************************************
1562 *****************************************************************/
1563 void city_dialog_update_output(struct city_dialog
*pdialog
)
1567 get_contents_of_output(pdialog
, buf
, sizeof(buf
));
1568 xaw_set_label(pdialog
->output_label
, buf
);
1571 /****************************************************************************
1572 Handle the callback when a citizen sprite widget is clicked.
1573 ****************************************************************************/
1574 static void citizen_callback(Widget w
, XtPointer client_data
,
1575 XtPointer call_data
)
1577 struct city_dialog
*pdialog
= client_data
;
1580 /* HACK: figure out which figure was clicked. */
1581 for (i
= 0; i
< city_size_get(pdialog
->pcity
); i
++) {
1582 if (pdialog
->citizen_labels
[i
] == w
) {
1586 fc_assert(i
< city_size_get(pdialog
->pcity
));
1588 city_rotate_specialist(pdialog
->pcity
, i
);
1591 /****************************************************************
1593 *****************************************************************/
1594 void city_dialog_update_citizens(struct city_dialog
*pdialog
)
1596 enum citizen_category categories
[MAX_CITY_SIZE
];
1598 struct city
*pcity
=pdialog
->pcity
;
1599 int num_citizens
= get_city_citizen_types(pcity
, FEELING_FINAL
, categories
);
1601 for (i
= 0; i
< num_citizens
&& i
< pdialog
->num_citizens_shown
; i
++) {
1602 xaw_set_bitmap(pdialog
->citizen_labels
[i
],
1603 get_citizen_pixmap(categories
[i
], i
, pcity
));
1605 /* HACK: set sensitivity/callbacks on the widget */
1606 XtRemoveAllCallbacks(pdialog
->citizen_labels
[i
], XtNcallback
);
1607 XtAddCallback(pdialog
->citizen_labels
[i
], XtNcallback
,
1608 citizen_callback
, (XtPointer
)pdialog
);
1609 XtSetSensitive(pdialog
->citizen_labels
[i
], TRUE
);
1612 if (i
>= pdialog
->num_citizens_shown
&& i
< num_citizens
) {
1613 i
= pdialog
->num_citizens_shown
- 1;
1614 /* FIXME: what about the mask? */
1615 xaw_set_bitmap(pdialog
->citizen_labels
[i
],
1616 get_arrow_sprite(tileset
, ARROW_RIGHT
)->pixmap
);
1617 XtSetSensitive(pdialog
->citizen_labels
[i
], FALSE
);
1618 XtRemoveAllCallbacks(pdialog
->citizen_labels
[i
], XtNcallback
);
1622 for(; i
<pdialog
->num_citizens_shown
; i
++) {
1623 xaw_set_bitmap(pdialog
->citizen_labels
[i
], None
);
1624 XtSetSensitive(pdialog
->citizen_labels
[i
], FALSE
);
1625 XtRemoveAllCallbacks(pdialog
->citizen_labels
[i
], XtNcallback
);
1629 /****************************************************************
1631 *****************************************************************/
1632 static void support_units_callback(Widget w
, XtPointer client_data
,
1633 XtPointer call_data
)
1636 XEvent
*e
= (XEvent
*)call_data
;
1637 struct unit
*punit
=
1638 player_unit_by_number(client_player(), (size_t) client_data
);
1640 if (NULL
!= punit
) {
1641 struct city
*pcity
= game_city_by_number(punit
->homecity
);
1643 if (NULL
!= pcity
) {
1644 struct city_dialog
*pdialog
= get_city_dialog(pcity
);
1646 if ( NULL
!= pdialog
) {
1647 if(e
->type
==ButtonRelease
&& e
->xbutton
.button
==Button2
) {
1648 unit_focus_set(punit
);
1649 close_city_dialog(pdialog
);
1652 if(e
->type
==ButtonRelease
&& e
->xbutton
.button
==Button3
) {
1653 unit_focus_set(punit
);
1656 wd
= popup_message_dialog(pdialog
->shell
,
1657 "supportunitsdialog",
1658 unit_description(punit
),
1659 supported_units_activate_callback
, punit
->id
, 1,
1660 supported_units_activate_close_callback
,
1662 disband_callback
, punit
->id
, 1,
1663 present_units_cancel_callback
, 0, 0,
1665 if (unit_has_type_flag(punit
, UTYF_UNDISBANDABLE
)) {
1666 XtSetSensitive(XtNameToWidget(wd
, "*button3"), FALSE
);
1674 /****************************************************************
1676 *****************************************************************/
1677 static int units_scroll_maintenance(int nunits
, int nshow
, int *base
,
1678 Widget next
, Widget prev
)
1683 nextra
=nunits
-nshow
;
1684 if (nextra
<0) nextra
=0;
1696 XtUnmapWidget(next
);
1697 XtUnmapWidget(prev
);
1701 XtSetSensitive(next
, *base
<nextra
);
1702 XtSetSensitive(prev
, *base
>0);
1708 /****************************************************************
1710 *****************************************************************/
1711 void city_dialog_update_supported_units(struct city_dialog
*pdialog
,
1714 struct unit_list
*plist
;
1717 int free_unhappy
= get_city_bonus(pdialog
->pcity
, EFT_MAKE_CONTENT_MIL
);
1719 if (NULL
!= client
.conn
.playing
1720 && city_owner(pdialog
->pcity
) != client
.conn
.playing
) {
1721 plist
= pdialog
->pcity
->client
.info_units_supported
;
1723 plist
= pdialog
->pcity
->units_supported
;
1726 adj_base
= units_scroll_maintenance(unit_list_size(plist
),
1727 pdialog
->num_units_shown
,
1728 &(pdialog
->support_unit_base
),
1729 pdialog
->support_unit_next_command
,
1730 pdialog
->support_unit_prev_command
);
1732 i
= 0; /* number of displayed units */
1733 j
= 0; /* index into list */
1734 unit_list_iterate(plist
, punit
) {
1735 struct canvas store
;
1736 int happy_cost
= city_unit_unhappiness(punit
, &free_unhappy
);
1738 if (j
++ < pdialog
->support_unit_base
) {
1741 if (i
>= pdialog
->num_units_shown
) {
1745 pixcomm
=pdialog
->support_unit_pixcomms
[i
];
1746 store
.pixmap
= XawPixcommPixmap(pixcomm
);
1748 if(!adj_base
&& unitid
&& punit
->id
!=unitid
)
1751 XawPixcommClear(pixcomm
); /* STG */
1752 put_unit(punit
, &store
, 1.0, 0, 0);
1753 put_unit_pixmap_city_overlays(punit
,
1754 XawPixcommPixmap(pixcomm
),
1755 punit
->upkeep
, happy_cost
);
1757 xaw_expose_now(pixcomm
);
1759 XtRemoveAllCallbacks(pixcomm
, XtNcallback
);
1760 XtAddCallback(pixcomm
, XtNcallback
,
1761 support_units_callback
, INT_TO_XTPOINTER(punit
->id
));
1762 XtSetSensitive(pixcomm
, TRUE
);
1764 } unit_list_iterate_end
;
1766 /* Disable any empty slots */
1767 for(; i
<pdialog
->num_units_shown
; i
++) {
1768 XawPixcommClear(pdialog
->support_unit_pixcomms
[i
]);
1769 XtSetSensitive(pdialog
->support_unit_pixcomms
[i
], FALSE
);
1773 /****************************************************************
1775 *****************************************************************/
1776 void city_dialog_update_present_units(struct city_dialog
*pdialog
, int unitid
)
1778 struct unit_list
*plist
;
1782 if (NULL
!= client
.conn
.playing
1783 && city_owner(pdialog
->pcity
) != client
.conn
.playing
) {
1784 plist
= pdialog
->pcity
->client
.info_units_present
;
1786 plist
= pdialog
->pcity
->tile
->units
;
1789 adj_base
= units_scroll_maintenance(unit_list_size(plist
),
1790 pdialog
->num_units_shown
,
1791 &(pdialog
->present_unit_base
),
1792 pdialog
->present_unit_next_command
,
1793 pdialog
->present_unit_prev_command
);
1795 i
= 0; /* number of displayed units */
1796 j
= 0; /* index into list */
1797 unit_list_iterate(plist
, punit
) {
1798 struct canvas store
;
1800 if (j
++ < pdialog
->present_unit_base
) {
1803 if (i
>= pdialog
->num_units_shown
) {
1807 pixcomm
=pdialog
->present_unit_pixcomms
[i
];
1808 store
.pixmap
= XawPixcommPixmap(pixcomm
);
1810 if(!adj_base
&& unitid
&& punit
->id
!=unitid
)
1813 XawPixcommClear(pixcomm
); /* STG */
1814 put_unit(punit
, &store
, 1.0, 0, 0);
1816 xaw_expose_now(pixcomm
);
1818 XtRemoveAllCallbacks(pixcomm
, XtNcallback
);
1819 XtAddCallback(pixcomm
, XtNcallback
,
1820 present_units_callback
, INT_TO_XTPOINTER(punit
->id
));
1821 XtSetSensitive(pixcomm
, TRUE
);
1823 } unit_list_iterate_end
;
1825 for(; i
<pdialog
->num_units_shown
; i
++) {
1826 XawPixcommClear(pdialog
->present_unit_pixcomms
[i
]);
1827 XtSetSensitive(pdialog
->present_unit_pixcomms
[i
], FALSE
);
1832 /****************************************************************
1834 *****************************************************************/
1835 void city_dialog_update_title(struct city_dialog
*pdialog
)
1840 fc_snprintf(buf
, sizeof(buf
), _("%s - %s citizens Governor: %s"),
1841 city_name_get(pdialog
->pcity
),
1842 population_to_text(city_population(pdialog
->pcity
)),
1843 cmafec_get_short_descr_of_city(pdialog
->pcity
));
1845 XtVaGetValues(pdialog
->cityname_label
, XtNlabel
, &now
, NULL
);
1846 if (strcmp(now
, buf
) != 0) {
1847 XtVaSetValues(pdialog
->cityname_label
, XtNlabel
, (XtArgVal
)buf
, NULL
);
1848 xaw_horiz_center(pdialog
->cityname_label
);
1849 XtVaSetValues(pdialog
->shell
, XtNtitle
,
1850 (XtArgVal
)city_name_get(pdialog
->pcity
), NULL
);
1854 /****************************************************************
1856 *****************************************************************/
1857 void city_dialog_update_improvement_list(struct city_dialog
*pdialog
)
1859 int n
= 0, flag
= 0;
1861 city_built_iterate(pdialog
->pcity
, pimprove
) {
1862 if (!pdialog
->improvlist_names_ptrs
[n
] ||
1863 strcmp(pdialog
->improvlist_names_ptrs
[n
],
1864 city_improvement_name_translation(pdialog
->pcity
, pimprove
)) != 0)
1866 sz_strlcpy(pdialog
->improvlist_names
[n
],
1867 city_improvement_name_translation(pdialog
->pcity
, pimprove
));
1868 pdialog
->improvlist_names_ptrs
[n
] = pdialog
->improvlist_names
[n
];
1870 } city_built_iterate_end
;
1872 if(pdialog
->improvlist_names_ptrs
[n
]!=0) {
1873 pdialog
->improvlist_names_ptrs
[n
]=0;
1878 XawListChange(pdialog
->improvement_list
, pdialog
->improvlist_names_ptrs
,
1880 /* force refresh of viewport so the scrollbar is added.
1881 * Buggy sun athena requires this */
1882 XtVaSetValues(pdialog
->improvement_viewport
, XtNforceBars
, False
, NULL
);
1883 XtVaSetValues(pdialog
->improvement_viewport
, XtNforceBars
, True
, NULL
);
1888 /**************************************************************************
1890 **************************************************************************/
1891 void citydlg_btn_select_citymap(Widget w
, XEvent
*event
)
1893 XButtonEvent
*ev
=&event
->xbutton
;
1894 struct city
*pcity
= NULL
;
1896 dialog_list_iterate(dialog_list
, pdialog
) {
1897 if (pdialog
->map_canvas
== w
) {
1898 pcity
= pdialog
->pcity
;
1901 } dialog_list_iterate_end
;
1904 if (!cma_is_city_under_agent(pcity
, NULL
)) {
1907 if (canvas_to_city_pos(&xtile
, &ytile
,
1908 city_map_radius_sq_get(pcity
), ev
->x
, ev
->y
)) {
1909 city_toggle_worker(pcity
, xtile
, ytile
);
1915 /****************************************************************
1917 *****************************************************************/
1918 static void buy_callback_yes(Widget w
, XtPointer client_data
,
1919 XtPointer call_data
)
1921 struct city_dialog
*pdialog
= client_data
;
1923 city_buy_production(pdialog
->pcity
);
1925 destroy_message_dialog(w
);
1929 /****************************************************************
1931 *****************************************************************/
1932 static void buy_callback_no(Widget w
, XtPointer client_data
,
1933 XtPointer call_data
)
1935 destroy_message_dialog(w
);
1939 /****************************************************************
1941 *****************************************************************/
1942 void buy_callback(Widget w
, XtPointer client_data
, XtPointer call_data
)
1944 char tbuf
[512], buf
[512];
1945 struct city_dialog
*pdialog
= (struct city_dialog
*)client_data
;;
1946 const char *name
= city_production_name_translation(pdialog
->pcity
);
1947 int value
= city_production_buy_gold_cost(pdialog
->pcity
);
1949 if (!can_client_issue_orders()) {
1953 fc_snprintf(tbuf
, ARRAY_SIZE(tbuf
), PL_("Treasury contains %d gold.",
1954 "Treasury contains %d gold.",
1955 client_player()->economic
.gold
),
1956 client_player()->economic
.gold
);
1958 if (value
<= client_player()->economic
.gold
) {
1959 fc_snprintf(buf
, sizeof(buf
),
1960 /* TRANS: Last %s is pre-pluralised "Treasury contains %d gold." */
1961 PL_("Buy %s for %d gold?\n%s",
1962 "Buy %s for %d gold?\n%s", value
),
1964 popup_message_dialog(pdialog
->shell
, "buydialog", buf
,
1965 buy_callback_yes
, pdialog
, 0,
1966 buy_callback_no
, 0, 0,
1970 fc_snprintf(buf
, sizeof(buf
),
1971 /* TRANS: Last %s is pre-pluralised "Treasury contains %d gold." */
1972 PL_("%s costs %d gold.\n%s",
1973 "%s costs %d gold.\n%s", value
),
1975 popup_message_dialog(pdialog
->shell
, "buynodialog", buf
,
1976 buy_callback_no
, 0, 0,
1983 /****************************************************************
1985 *****************************************************************/
1986 void unitupgrade_callback_yes(Widget w
, XtPointer client_data
, XtPointer call_data
)
1988 struct unit
*punit
=
1989 player_unit_by_number(client_player(), (size_t)client_data
);
1991 /* Is it right place for breaking? -ev */
1992 if (!can_client_issue_orders()) {
1996 if (NULL
!= punit
) {
1997 request_unit_upgrade(punit
);
2000 destroy_message_dialog(w
);
2004 /****************************************************************
2006 *****************************************************************/
2007 void unitupgrade_callback_no(Widget w
, XtPointer client_data
, XtPointer call_data
)
2009 destroy_message_dialog(w
);
2013 /****************************************************************
2015 *****************************************************************/
2016 void upgrade_callback(Widget w
, XtPointer client_data
, XtPointer call_data
)
2019 struct unit
*punit
= player_unit_by_number(client_player(),
2020 (size_t) client_data
);
2026 if (UU_OK
== unit_upgrade_info(punit
, buf
, sizeof(buf
))) {
2027 popup_message_dialog(toplevel
, "upgradedialog", buf
,
2028 unitupgrade_callback_yes
,
2029 INT_TO_XTPOINTER(punit
->id
), 0,
2030 unitupgrade_callback_no
, 0, 0, NULL
);
2032 popup_message_dialog(toplevel
, "upgradenodialog", buf
,
2033 unitupgrade_callback_no
, 0, 0,
2037 destroy_message_dialog(w
);
2041 /****************************************************************
2043 *****************************************************************/
2044 void disband_callback(Widget w
, XtPointer client_data
, XtPointer call_data
)
2046 struct unit
*punit
= player_unit_by_number(client_player(),
2047 (size_t) client_data
);
2048 struct unit_list
*punits
;
2054 punits
= unit_list_new();
2055 unit_list_append(punits
, punit
);
2056 popup_disband_dialog(punits
);
2057 unit_list_destroy(punits
);
2058 destroy_message_dialog(w
);
2062 /****************************************************************
2063 Production change callback
2064 *****************************************************************/
2065 static void change_to_callback(Widget w
, XtPointer client_data
,
2066 XtPointer call_data
)
2068 struct city_dialog
*pdialog
;
2069 XawListReturnStruct
*ret
;
2071 pdialog
= (struct city_dialog
*)client_data
;
2073 ret
= XawListShowCurrent(pdialog
->change_list
);
2075 if (ret
->list_index
!= XAW_LIST_NONE
) {
2076 struct universal target
=
2077 universal_by_number((ret
->list_index
>= pdialog
->change_list_num_improvements
)
2078 ? VUT_UTYPE
: VUT_IMPROVEMENT
,
2079 pdialog
->change_list_ids
[ret
->list_index
]);
2081 city_change_production(pdialog
->pcity
, &target
);
2084 XtDestroyWidget(XtParent(XtParent(w
)));
2085 XtSetSensitive(pdialog
->shell
, TRUE
);
2088 /****************************************************************
2090 *****************************************************************/
2091 static void change_no_callback(Widget w
, XtPointer client_data
,
2092 XtPointer call_data
)
2094 struct city_dialog
*pdialog
;
2096 pdialog
=(struct city_dialog
*)client_data
;
2098 XtDestroyWidget(XtParent(XtParent(w
)));
2099 XtSetSensitive(pdialog
->shell
, TRUE
);
2102 /****************************************************************
2104 *****************************************************************/
2105 static void change_help_callback(Widget w
, XtPointer client_data
,
2106 XtPointer call_data
)
2108 struct city_dialog
*pdialog
;
2109 XawListReturnStruct
*ret
;
2111 pdialog
=(struct city_dialog
*)client_data
;
2113 ret
=XawListShowCurrent(pdialog
->change_list
);
2114 if(ret
->list_index
!=XAW_LIST_NONE
) {
2115 int idx
= pdialog
->change_list_ids
[ret
->list_index
];
2116 bool is_unit
= (ret
->list_index
>= pdialog
->change_list_num_improvements
);
2119 popup_help_dialog_typed(utype_name_translation(utype_by_number(idx
)), HELP_UNIT
);
2120 } else if (is_great_wonder(improvement_by_number(idx
))) {
2121 popup_help_dialog_typed(improvement_name_translation(improvement_by_number(idx
)), HELP_WONDER
);
2123 popup_help_dialog_typed(improvement_name_translation(improvement_by_number(idx
)), HELP_IMPROVEMENT
);
2127 popup_help_dialog_string(HELP_IMPROVEMENTS_ITEM
);
2131 /****************************************************************
2133 *****************************************************************/
2134 void change_callback(Widget w
, XtPointer client_data
, XtPointer call_data
)
2136 static char *dummy_change_list
[]={
2137 "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 888 turns",
2155 Widget cshell
, cform
, clabel
, cview
, button_change
, button_cancel
, button_help
;
2157 Dimension width
, height
;
2158 struct city_dialog
*pdialog
;
2159 struct universal production
;
2162 pdialog
=(struct city_dialog
*)client_data
;
2164 I_T(cshell
=XtCreatePopupShell("changedialog", transientShellWidgetClass
,
2165 pdialog
->shell
, NULL
, 0));
2167 cform
=XtVaCreateManagedWidget("dform", formWidgetClass
, cshell
, NULL
);
2169 I_L(clabel
=XtVaCreateManagedWidget("dlabel", labelWidgetClass
, cform
,
2172 cview
=XtVaCreateManagedWidget("dview", viewportWidgetClass
,
2178 pdialog
->change_list
=XtVaCreateManagedWidget("dlist", listWidgetClass
,
2181 XtNdefaultColumns
,1,
2183 (XtArgVal
)dummy_change_list
,
2184 XtNverticalList
, False
,
2188 button_change
= I_L(XtVaCreateManagedWidget("buttonchange",
2195 button_cancel
= I_L(XtVaCreateManagedWidget("buttoncancel",
2204 button_help
= I_L(XtVaCreateManagedWidget("buttonhelp",
2213 XtAddCallback(button_change
, XtNcallback
,
2214 change_to_callback
, (XtPointer
)pdialog
);
2215 XtAddCallback(button_cancel
, XtNcallback
,
2216 change_no_callback
, (XtPointer
)pdialog
);
2217 XtAddCallback(button_help
, XtNcallback
,
2218 change_help_callback
, (XtPointer
)pdialog
);
2222 XtVaGetValues(pdialog
->shell
, XtNwidth
, &width
, XtNheight
, &height
, NULL
);
2223 XtTranslateCoords(pdialog
->shell
, (Position
) width
/6, (Position
) height
/10,
2225 XtVaSetValues(cshell
, XtNx
, x
, XtNy
, y
, NULL
);
2227 XtPopup(cshell
, XtGrabNone
);
2229 XtSetSensitive(pdialog
->shell
, FALSE
);
2232 improvement_iterate(pimprove
) {
2233 if (can_city_build_improvement_now(pdialog
->pcity
, pimprove
)) {
2234 production
.kind
= VUT_IMPROVEMENT
;
2235 production
.value
.building
= pimprove
;
2236 get_city_dialog_production_full(pdialog
->change_list_names
[n
],
2237 sizeof(pdialog
->change_list_names
[n
]),
2238 &production
, pdialog
->pcity
);
2239 pdialog
->change_list_names_ptrs
[n
] = pdialog
->change_list_names
[n
];
2240 pdialog
->change_list_ids
[n
++] = improvement_number(pimprove
);
2242 } improvement_iterate_end
;
2244 pdialog
->change_list_num_improvements
= n
;
2246 unit_type_iterate(punittype
) {
2247 if (can_city_build_unit_now(pdialog
->pcity
, punittype
)) {
2248 production
.kind
= VUT_UTYPE
;
2249 production
.value
.utype
= punittype
;
2250 get_city_dialog_production_full(pdialog
->change_list_names
[n
],
2251 sizeof(pdialog
->change_list_names
[n
]),
2252 &production
, pdialog
->pcity
);
2253 pdialog
->change_list_names_ptrs
[n
] = pdialog
->change_list_names
[n
];
2254 pdialog
->change_list_ids
[n
++] = utype_number(punittype
);
2256 } unit_type_iterate_end
;
2258 pdialog
->change_list_names_ptrs
[n
] = 0;
2260 XawListChange(pdialog
->change_list
, pdialog
->change_list_names_ptrs
,
2262 /* force refresh of viewport so the scrollbar is added.
2263 * Buggy sun athena requires this */
2264 XtVaSetValues(cview
, XtNforceBars
, True
, NULL
);
2268 /****************************************************************
2269 Display the city's worklist.
2270 *****************************************************************/
2271 void worklist_callback(Widget w
, XtPointer client_data
, XtPointer call_data
)
2273 struct city_dialog
*pdialog
;
2275 pdialog
= (struct city_dialog
*)client_data
;
2277 if (pdialog
->worklist_shell
) {
2278 XtPopup(pdialog
->worklist_shell
, XtGrabNone
);
2280 pdialog
->worklist_shell
=
2281 popup_worklist(pdialog
->pcity
, NULL
,
2282 pdialog
->shell
, (void *) pdialog
, commit_city_worklist
,
2283 cancel_city_worklist
);
2287 /****************************************************************
2288 Commit the changes to the worklist for the city.
2289 *****************************************************************/
2290 void commit_city_worklist(struct worklist
*pwl
, void *data
)
2292 struct city_dialog
*pdialog
= data
;
2294 city_worklist_commit(pdialog
->pcity
, pwl
);
2297 void cancel_city_worklist(void *data
) {
2298 struct city_dialog
*pdialog
= (struct city_dialog
*)data
;
2299 pdialog
->worklist_shell
= NULL
;
2302 /****************************************************************
2304 *****************************************************************/
2305 static void sell_callback_yes(Widget w
, XtPointer client_data
,
2306 XtPointer call_data
)
2308 struct city_dialog
*pdialog
= client_data
;
2310 city_sell_improvement(pdialog
->pcity
, pdialog
->sell_id
);
2312 destroy_message_dialog(w
);
2316 /****************************************************************
2318 *****************************************************************/
2319 static void sell_callback_no(Widget w
, XtPointer client_data
,
2320 XtPointer call_data
)
2322 destroy_message_dialog(w
);
2326 /****************************************************************
2328 *****************************************************************/
2329 void sell_callback(Widget w
, XtPointer client_data
, XtPointer call_data
)
2331 struct city_dialog
*pdialog
;
2332 XawListReturnStruct
*ret
;
2334 pdialog
=(struct city_dialog
*)client_data
;
2336 ret
=XawListShowCurrent(pdialog
->improvement_list
);
2338 if(ret
->list_index
!=XAW_LIST_NONE
) {
2340 city_built_iterate(pdialog
->pcity
, pimprove
) {
2341 if (n
== ret
->list_index
) {
2345 if (!can_city_sell_building(pdialog
->pcity
, pimprove
)) {
2349 pdialog
->sell_id
= improvement_number(pimprove
);
2350 price
= impr_sell_gold(pimprove
);
2351 fc_snprintf(buf
, sizeof(buf
), PL_("Sell %s for %d gold?",
2352 "Sell %s for %d gold?", price
),
2353 city_improvement_name_translation(pdialog
->pcity
, pimprove
),
2356 popup_message_dialog(pdialog
->shell
, "selldialog", buf
,
2357 sell_callback_yes
, pdialog
, 0,
2358 sell_callback_no
, pdialog
, 0, NULL
);
2363 } city_built_iterate_end
;
2367 /****************************************************************
2369 *****************************************************************/
2370 void close_city_dialog(struct city_dialog
*pdialog
)
2372 if (pdialog
->worklist_shell
)
2373 XtDestroyWidget(pdialog
->worklist_shell
);
2375 XtDestroyWidget(pdialog
->shell
);
2376 dialog_list_remove(dialog_list
, pdialog
);
2378 free(pdialog
->citizen_labels
);
2380 free(pdialog
->support_unit_pixcomms
);
2381 free(pdialog
->present_unit_pixcomms
);
2384 if(pdialog->is_modal)
2385 XtSetSensitive(toplevel, TRUE);
2388 popdown_cma_dialog();
2391 /****************************************************************
2393 *****************************************************************/
2394 void citydlg_key_close(Widget w
)
2396 citydlg_msg_close(XtParent(XtParent(w
)));
2399 /****************************************************************
2401 *****************************************************************/
2402 void citydlg_msg_close(Widget w
)
2404 dialog_list_iterate(dialog_list
, pdialog
) {
2405 if (pdialog
->shell
== w
) {
2406 close_city_dialog(pdialog
);
2409 } dialog_list_iterate_end
;
2412 /****************************************************************
2414 *****************************************************************/
2415 void close_callback(Widget w
, XtPointer client_data
, XtPointer call_data
)
2417 close_city_dialog((struct city_dialog
*)client_data
);
2421 /****************************************************************
2423 City Options dialog: (current only auto-attack options)
2425 Note, there can only be one such dialog at a time, because
2426 I'm lazy. That could be fixed, similar to way you can have
2427 multiple city dialogs.
2429 triggle = tri_toggle (three way toggle button)
2431 *****************************************************************/
2433 #define NUM_CITYOPT_TOGGLES 5
2435 Widget
create_cityopt_dialog(const char *cityname
);
2436 void cityopt_ok_command_callback(Widget w
, XtPointer client_data
,
2437 XtPointer call_data
);
2438 void cityopt_cancel_command_callback(Widget w
, XtPointer client_data
,
2439 XtPointer call_data
);
2440 void cityopt_newcit_triggle_callback(Widget w
, XtPointer client_data
,
2441 XtPointer call_data
);
2443 char *newcitizen_labels
[] = {
2449 static Widget cityopt_shell
= 0;
2450 static Widget cityopt_triggle
;
2451 static Widget cityopt_toggles
[NUM_CITYOPT_TOGGLES
];
2452 static int cityopt_city_id
= 0;
2453 static int newcitizen_index
;
2455 /****************************************************************
2457 *****************************************************************/
2458 void cityopt_callback(Widget w
, XtPointer client_data
,
2459 XtPointer call_data
)
2461 struct city_dialog
*pdialog
= (struct city_dialog
*)client_data
;
2462 struct city
*pcity
= pdialog
->pcity
;
2465 if (cityopt_shell
) {
2466 XtDestroyWidget(cityopt_shell
);
2469 cityopt_shell
= create_cityopt_dialog(city_name_get(pcity
));
2471 /* Doing this here makes the "No"'s centered consistently */
2472 for (i
= 0; i
< NUM_CITYOPT_TOGGLES
; i
++) {
2473 bool state
= is_city_option_set(pcity
, i
);
2475 XtVaSetValues(cityopt_toggles
[i
], XtNstate
, state
,
2476 XtNlabel
, state
?_("Yes"):_("No"), NULL
);
2479 if (is_city_option_set(pcity
, CITYO_NEW_EINSTEIN
)) {
2480 newcitizen_index
= 1;
2481 } else if (is_city_option_set(pcity
, CITYO_NEW_TAXMAN
)) {
2482 newcitizen_index
= 2;
2484 newcitizen_index
= 0;
2487 XtVaSetValues(cityopt_triggle
, XtNstate
, 1,
2488 XtNlabel
, _(newcitizen_labels
[newcitizen_index
]),
2491 cityopt_city_id
= pcity
->id
;
2493 xaw_set_relative_position(pdialog
->shell
, cityopt_shell
, 15, 15);
2494 XtPopup(cityopt_shell
, XtGrabNone
);
2498 /**************************************************************************
2500 **************************************************************************/
2501 Widget
create_cityopt_dialog(const char *cityname
)
2503 Widget shell
, form
, label
, ok
, cancel
;
2506 shell
= I_T(XtCreatePopupShell("cityoptpopup",
2507 transientShellWidgetClass
,
2508 toplevel
, NULL
, 0));
2509 form
= XtVaCreateManagedWidget("cityoptform",
2512 label
= XtVaCreateManagedWidget("cityoptlabel", labelWidgetClass
,
2513 form
, XtNlabel
, cityname
, NULL
);
2516 I_L(XtVaCreateManagedWidget("cityoptnewcitlabel", labelWidgetClass
,
2519 cityopt_triggle
= XtVaCreateManagedWidget("cityoptnewcittriggle",
2523 /* NOTE: the ordering here is deliberately out of order;
2524 want toggles[] to be in enum city_options order, but
2525 want display in different order. --dwp
2526 - disband and workers options at top
2527 - helicopters (special case air) at bottom
2530 I_L(XtVaCreateManagedWidget("cityoptdisbandlabel", labelWidgetClass
,
2533 cityopt_toggles
[4] = XtVaCreateManagedWidget("cityoptdisbandtoggle",
2537 I_L(XtVaCreateManagedWidget("cityoptvlandlabel", labelWidgetClass
,
2540 cityopt_toggles
[0] = XtVaCreateManagedWidget("cityoptvlandtoggle",
2544 I_L(XtVaCreateManagedWidget("cityoptvsealabel", labelWidgetClass
,
2547 cityopt_toggles
[1] = XtVaCreateManagedWidget("cityoptvseatoggle",
2551 I_L(XtVaCreateManagedWidget("cityoptvairlabel", labelWidgetClass
,
2554 cityopt_toggles
[3] = XtVaCreateManagedWidget("cityoptvairtoggle",
2558 I_L(XtVaCreateManagedWidget("cityoptvhelilabel", labelWidgetClass
,
2561 cityopt_toggles
[2] = XtVaCreateManagedWidget("cityoptvhelitoggle",
2565 ok
= I_L(XtVaCreateManagedWidget("cityoptokcommand",
2569 cancel
= I_L(XtVaCreateManagedWidget("cityoptcancelcommand",
2573 XtAddCallback(ok
, XtNcallback
, cityopt_ok_command_callback
,
2575 XtAddCallback(cancel
, XtNcallback
, cityopt_cancel_command_callback
,
2577 for(i
=0; i
<NUM_CITYOPT_TOGGLES
; i
++) {
2578 XtAddCallback(cityopt_toggles
[i
], XtNcallback
, toggle_callback
, NULL
);
2580 XtAddCallback(cityopt_triggle
, XtNcallback
,
2581 cityopt_newcit_triggle_callback
, NULL
);
2583 XtRealizeWidget(shell
);
2585 xaw_horiz_center(label
);
2589 /**************************************************************************
2591 **************************************************************************/
2592 void cityopt_cancel_command_callback(Widget w
, XtPointer client_data
,
2593 XtPointer call_data
)
2595 XtDestroyWidget(cityopt_shell
);
2599 /**************************************************************************
2601 **************************************************************************/
2602 void cityopt_ok_command_callback(Widget w
, XtPointer client_data
,
2603 XtPointer call_data
)
2605 struct city
*pcity
= game_city_by_number(cityopt_city_id
);
2609 bv_city_options new_options
;
2612 fc_assert(CITYO_LAST
== 3);
2614 BV_CLR_ALL(new_options
);
2615 /* for(i=0; i<NUM_CITYOPT_TOGGLES; i++) {
2616 XtVaGetValues(cityopt_toggles[i], XtNstate, &b, NULL);
2617 if (b) new_options |= (1<<i);
2620 XtVaGetValues(cityopt_toggles
[4], XtNstate
, &b
, NULL
);
2622 BV_SET(new_options
, CITYO_DISBAND
);
2624 if (newcitizen_index
== 1) {
2625 BV_SET(new_options
, CITYO_NEW_EINSTEIN
);
2626 } else if (newcitizen_index
== 2) {
2627 BV_SET(new_options
, CITYO_NEW_TAXMAN
);
2629 dsend_packet_city_options_req(&client
.conn
, cityopt_city_id
,new_options
);
2631 XtDestroyWidget(cityopt_shell
);
2635 /**************************************************************************
2636 Changes the label of the toggle widget to between newcitizen_labels
2637 and increments (mod 3) newcitizen_index.
2638 **************************************************************************/
2639 void cityopt_newcit_triggle_callback(Widget w
, XtPointer client_data
,
2640 XtPointer call_data
)
2643 if (newcitizen_index
>=3) {
2644 newcitizen_index
= 0;
2646 XtVaSetValues(cityopt_triggle
, XtNstate
, 1,
2647 XtNlabel
, _(newcitizen_labels
[newcitizen_index
]),
2651 /**************************************************************************
2653 **************************************************************************/
2654 void popdown_cityopt_dialog(void)
2657 XtDestroyWidget(cityopt_shell
);
2662 /****************************************************************
2663 The user clicked on the "CMA..." button in the citydialog.
2664 *****************************************************************/
2665 void cma_callback(Widget w
, XtPointer client_data
,
2666 XtPointer call_data
)
2668 struct city_dialog
*pdialog
= (struct city_dialog
*)client_data
;
2669 popdown_cma_dialog();
2670 show_cma_dialog(pdialog
->pcity
, pdialog
->shell
);