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>
22 #include <X11/Intrinsic.h>
23 #include <X11/StringDefs.h>
24 #include <X11/Xaw/AsciiText.h>
25 #include <X11/Xaw/Command.h>
26 #include <X11/Xaw/Form.h>
27 #include <X11/Xaw/Label.h>
28 #include <X11/Xaw/List.h>
29 #include <X11/Xaw/MenuButton.h>
30 #include <X11/Xaw/SimpleMenu.h>
31 #include <X11/Xaw/SmeBSB.h>
32 #include <X11/Xaw/Toggle.h>
33 #include <X11/Xaw/Viewport.h> /* for racesdlg */
36 #include "bitvector.h"
45 #include "government.h"
53 #include "cityrep.h" /* city_report_dialog_popdown() */
54 #include "client_main.h"
56 #include "control.h" /* request_xxx and unit_focus_set */
59 #include "gui_stuff.h"
61 #include "mapctrl_common.h"
63 #include "messagewin.h" /* meswin_dialog_popdown() */
66 #include "plrdlg.h" /* for popdown_players_dialog */
67 #include "repodlgs.h" /* for popdown_xxx_dialog */
73 /******************************************************************/
74 void popdown_notify_dialog(void);
75 static Widget notify_dialog_shell
;
77 /******************************************************************/
78 static Widget races_dialog_shell
=NULL
;
79 static Widget races_form
, races_toggles_form
, races_label
;
80 static Widget races_toggles_viewport
;
81 static Widget
*races_toggles
=NULL
;
82 static struct nation_type
**races_toggles_to_nations
= NULL
;
83 static int *nation_idx_to_race_toggle
= NULL
;
84 struct player
*races_player
;
85 static Widget races_leader_form
, races_leader
;
86 static Widget races_leader_pick_popupmenu
, races_leader_pick_menubutton
;
87 static Widget races_sex_toggles
[2], races_sex_form
, races_sex_label
;
88 static Widget races_style_form
, races_style_label
;
89 static Widget
*races_style_toggles
=NULL
;
90 static Widget races_action_form
;
91 static Widget races_ok_command
, races_random_command
, races_quit_command
;
94 /******************************************************************/
95 #define MAX_SELECT_UNITS 100
96 static Widget unit_select_dialog_shell
;
97 static Widget unit_select_form
;
98 static Widget unit_select_commands
[MAX_SELECT_UNITS
];
99 static Widget unit_select_labels
[MAX_SELECT_UNITS
];
100 static Pixmap unit_select_pixmaps
[MAX_SELECT_UNITS
];
101 static int unit_select_ids
[MAX_SELECT_UNITS
];
102 static int unit_select_no
;
104 void about_button_callback(Widget w
, XtPointer client_data
,
105 XtPointer call_data
);
107 void help_button_callback(Widget w
, XtPointer client_data
,
108 XtPointer call_data
);
110 void create_rates_dialog(void);
111 void create_about_dialog(void);
112 void create_help_dialog(Widget
*shell
);
115 /******************************************************************/
116 static void create_races_dialog(struct player
*pplayer
);
117 static void races_leader_set_values(struct nation_type
*race
, int lead
);
118 static int races_buttons_get_current(void);
119 static int races_sex_buttons_get_current(void);
120 static int races_style_buttons_get_current(void);
121 static void races_sex_buttons_set_current(int i
);
123 static int races_indirect_compare(const void *first
, const void *second
);
125 static void races_toggles_callback(Widget w
, XtPointer client_data
,
126 XtPointer call_data
);
127 static void races_leader_pick_callback(Widget w
, XtPointer client_data
,
128 XtPointer call_data
);
129 static void races_ok_command_callback(Widget w
, XtPointer client_data
,
130 XtPointer call_data
);
131 static void races_random_command_callback(Widget w
, XtPointer client_data
,
132 XtPointer call_data
);
133 static void races_quit_command_callback(Widget w
, XtPointer client_data
,
134 XtPointer call_data
);
136 /******************************************************************/
137 void unit_select_callback(Widget w
, XtPointer client_data
,
138 XtPointer call_data
);
139 void unit_select_all_callback(Widget w
, XtPointer client_data
,
140 XtPointer call_data
);
143 /******************************************************************/
144 static int city_style_idx
[64]; /* translation table basic style->city_style */
145 static int city_style_ridx
[64]; /* translation table the other way */
146 /* they in fact limit the num of styles to 64 */
148 /******************************************************************/
150 int is_showing_pillage_dialog
= FALSE
;
151 int unit_to_use_to_pillage
;
153 /****************************************************************
155 *****************************************************************/
156 static void notify_command_callback(Widget w
, XtPointer client_data
,
159 popdown_notify_dialog();
162 /****************************************************************
164 *****************************************************************/
165 static void select_random_race(void)
167 /* try to find a free nation */
168 /* FIXME: this code should be done another way. -ev */
170 unsigned int race_toggle_index
= fc_rand(nation_count());
171 const struct nation_type
*pnation
=
172 races_toggles_to_nations
[race_toggle_index
];
175 || !is_nation_playable(pnation
)
176 || !is_nation_pickable(pnation
)
177 || pnation
->player
) {
180 if (XtIsSensitive(races_toggles
[race_toggle_index
])) {
181 x_simulate_button_click(races_toggles
[race_toggle_index
]);
187 /**************************************************************************
188 Popup a generic dialog to display some generic information.
189 **************************************************************************/
190 void popup_notify_dialog(const char *caption
, const char *headline
,
193 Widget notify_form
, notify_command
;
194 Widget notify_headline
, notify_label
;
195 Dimension width
, width2
;
197 notify_dialog_shell
= XtCreatePopupShell(caption
,
198 transientShellWidgetClass
,
201 notify_form
= XtVaCreateManagedWidget("notifyform",
203 notify_dialog_shell
, NULL
);
205 notify_headline
=XtVaCreateManagedWidget("notifyheadline",
206 labelWidgetClass
, notify_form
,
211 notify_label
=XtVaCreateManagedWidget("notifylabel",
212 labelWidgetClass
, notify_form
,
217 I_L(XtVaCreateManagedWidget("notifycommand",
222 XtVaGetValues(notify_label
, XtNwidth
, &width
, NULL
);
223 XtVaGetValues(notify_headline
, XtNwidth
, &width2
, NULL
);
225 XtVaSetValues(notify_headline
, XtNwidth
, width
, NULL
);
227 XtAddCallback(notify_command
, XtNcallback
, notify_command_callback
, NULL
);
229 xaw_set_relative_position(toplevel
, notify_dialog_shell
, 25, 5);
230 XtPopup(notify_dialog_shell
, XtGrabNone
);
231 XtSetSensitive(toplevel
, FALSE
);
234 /****************************************************************
235 Closes the notification dialog.
236 *****************************************************************/
237 void popdown_notify_dialog(void)
239 if (notify_dialog_shell
) {
240 XtDestroyWidget(notify_dialog_shell
);
241 XtSetSensitive(toplevel
, TRUE
);
242 notify_dialog_shell
= 0;
246 /****************************************************************
248 *****************************************************************/
250 /* surely this should use genlists?? --dwp */
254 struct widget_list
*next
;
256 static struct widget_list
*notify_goto_widget_list
= NULL
;
258 static void notify_goto_widget_remove(Widget w
)
260 struct widget_list
*cur
, *tmp
;
261 cur
=notify_goto_widget_list
;
264 if (cur
&& cur
->w
== w
) {
266 free(notify_goto_widget_list
);
267 notify_goto_widget_list
= cur
;
270 for (; cur
->next
&& cur
->next
->w
!= w
; cur
=cur
->next
);
273 cur
->next
= cur
->next
->next
;
278 static struct tile
*notify_goto_find_widget(Widget w
)
280 struct widget_list
*cur
;
282 for (cur
= notify_goto_widget_list
; cur
&& cur
->w
!=w
; cur
= cur
->next
) {
293 static void notify_goto_add_widget_tile(Widget w
, struct tile
*ptile
)
295 struct widget_list
*newwidget
;
297 newwidget
= fc_malloc(sizeof(*newwidget
));
299 newwidget
->tile
= ptile
;
300 newwidget
->next
= notify_goto_widget_list
;
301 notify_goto_widget_list
= newwidget
;
304 static void notify_goto_command_callback(Widget w
, XtPointer client_data
,
307 struct tile
*ptile
= notify_goto_find_widget(w
);
309 center_tile_mapcanvas(ptile
);
310 notify_goto_widget_remove(w
);
312 XtDestroyWidget(XtParent(XtParent(w
)));
313 XtSetSensitive(toplevel
, TRUE
);
316 static void notify_no_goto_command_callback(Widget w
, XtPointer client_data
,
319 notify_goto_widget_remove(w
);
320 XtDestroyWidget(XtParent(XtParent(w
)));
321 XtSetSensitive(toplevel
, TRUE
);
325 /**************************************************************************
326 Popup a dialog to display information about an event that has a
327 specific location. The user should be given the option to goto that
329 **************************************************************************/
330 void popup_notify_goto_dialog(const char *headline
, const char *lines
,
331 const struct text_tag_list
*tags
,
334 Widget notify_gdialog_shell
, notify_form
, notify_command
, notify_goto_command
;
335 Widget notify_headline
, notify_label
;
336 Dimension width
, width2
, width_1
, width_2
;
339 popup_notify_dialog("Message:", headline
, lines
);
342 notify_gdialog_shell
= XtCreatePopupShell("Message:",
343 transientShellWidgetClass
,
346 notify_form
= XtVaCreateManagedWidget("notifyform",
348 notify_gdialog_shell
, NULL
);
350 notify_headline
=XtVaCreateManagedWidget("notifyheadline",
351 labelWidgetClass
, notify_form
,
356 notify_label
=XtVaCreateManagedWidget("notifylabel",
357 labelWidgetClass
, notify_form
,
362 I_L(XtVaCreateManagedWidget("notifycommand",
367 notify_goto_command
=
368 I_L(XtVaCreateManagedWidget("notifygotocommand",
373 XtVaGetValues(notify_label
, XtNwidth
, &width
, NULL
);
374 XtVaGetValues(notify_headline
, XtNwidth
, &width2
, NULL
);
375 XtVaGetValues(notify_command
, XtNwidth
, &width_1
, NULL
);
376 XtVaGetValues(notify_goto_command
, XtNwidth
, &width_2
, NULL
);
377 if (width_1
+ width_2
> width
) width
= width_1
+ width_2
;
379 XtVaSetValues(notify_headline
, XtNwidth
, width
, NULL
);
381 XtAddCallback(notify_command
, XtNcallback
, notify_no_goto_command_callback
, NULL
);
382 XtAddCallback(notify_goto_command
, XtNcallback
, notify_goto_command_callback
, NULL
);
383 notify_goto_add_widget_tile(notify_goto_command
, ptile
);
384 xaw_set_relative_position(toplevel
, notify_gdialog_shell
, 25, 5);
385 XtPopup(notify_gdialog_shell
, XtGrabNone
);
386 /* XtSetSensitive(toplevel, FALSE); */
389 /**************************************************************************
390 Popup a dialog to display connection message from server.
391 **************************************************************************/
392 void popup_connect_msg(const char *headline
, const char *message
)
394 /* FIXME: Needs proper implementation.
395 * Now just puts to chat window so message is not completely lost. */
397 output_window_append(ftc_client
, message
);
400 /****************************************************************
402 *****************************************************************/
403 static void revolution_callback_yes(Widget w
, XtPointer client_data
,
406 struct government
*pgovernment
= client_data
;
411 /* Player have choosed government */
412 set_government_choice(pgovernment
);
414 destroy_message_dialog(w
);
417 /****************************************************************
419 *****************************************************************/
420 static void revolution_callback_no(Widget w
, XtPointer client_data
,
423 destroy_message_dialog(w
);
428 /****************************************************************
430 *****************************************************************/
431 void popup_revolution_dialog(struct government
*pgovernment
)
433 popup_message_dialog(toplevel
, "revolutiondialog",
434 _("You say you wanna revolution?"),
435 revolution_callback_yes
, pgovernment
, 0,
436 revolution_callback_no
, 0, 0,
440 /**************************************************************************
441 User requested closing of pillage dialog.
442 **************************************************************************/
443 static void pillage_callback(Widget w
, XtPointer client_data
,
446 if (!is_showing_pillage_dialog
) {
447 destroy_message_dialog (w
);
452 struct unit
*punit
= game_unit_by_number(unit_to_use_to_pillage
);
454 struct extra_type
*target
;
455 int what
= XTPOINTER_TO_INT(client_data
);
457 target
= extra_by_number(what
);
459 request_new_unit_activity_targeted(punit
, ACTIVITY_PILLAGE
,
464 destroy_message_dialog (w
);
465 is_showing_pillage_dialog
= FALSE
;
468 /**************************************************************************
469 Popup a dialog asking the unit which improvement they would like to
471 **************************************************************************/
472 void popup_pillage_dialog(struct unit
*punit
, bv_extras extras
)
474 Widget shell
, form
, dlabel
, button
, prev
;
475 struct extra_type
*tgt
;
477 if (is_showing_pillage_dialog
) {
480 is_showing_pillage_dialog
= TRUE
;
481 unit_to_use_to_pillage
= punit
->id
;
483 XtSetSensitive (toplevel
, FALSE
);
485 shell
= I_T(XtCreatePopupShell("pillagedialog", transientShellWidgetClass
,
487 form
= XtVaCreateManagedWidget ("form", formWidgetClass
, shell
, NULL
);
488 dlabel
= I_L(XtVaCreateManagedWidget("dlabel", labelWidgetClass
, form
, NULL
));
491 while ((tgt
= get_preferred_pillage(extras
))) {
494 what
= extra_index(tgt
);
496 BV_CLR(extras
, what
);
499 XtVaCreateManagedWidget ("button", commandWidgetClass
, form
,
502 (XtArgVal
)(extra_name_translation(tgt
)),
504 XtAddCallback(button
, XtNcallback
, pillage_callback
,
505 INT_TO_XTPOINTER(what
));
510 I_L(XtVaCreateManagedWidget("closebutton", commandWidgetClass
, form
,
513 XtAddCallback (button
, XtNcallback
, pillage_callback
, NULL
);
515 xaw_set_relative_position (toplevel
, shell
, 10, 0);
516 XtPopup (shell
, XtGrabNone
);
519 /****************************************************************
521 *****************************************************************/
522 static void unitdisband_callback_yes(Widget w
, XtPointer client_data
, XtPointer call_data
)
524 struct unit_list
*punits
= client_data
;
526 /* Is it right place for breaking? -ev */
527 if (!can_client_issue_orders()) {
528 unit_list_destroy(punits
);
532 unit_list_iterate(punits
, punit
) {
533 if (!unit_has_type_flag(punit
, UTYF_UNDISBANDABLE
)) {
534 request_unit_disband(punit
);
536 } unit_list_iterate_end
;
538 unit_list_destroy(punits
);
539 destroy_message_dialog(w
);
543 /****************************************************************
545 *****************************************************************/
546 static void unitdisband_callback_no(Widget w
, XtPointer client_data
, XtPointer call_data
)
548 destroy_message_dialog(w
);
552 /****************************************************************
554 *****************************************************************/
555 void popup_disband_dialog(struct unit_list
*punits
)
559 if (get_units_disband_info(buf
, sizeof(buf
), punits
)) {
560 struct unit_list
*punits2
= unit_list_copy(punits
);
561 popup_message_dialog(toplevel
, "disbanddialog", buf
,
562 unitdisband_callback_yes
,
564 unitdisband_callback_no
, 0, 0, NULL
);
566 popup_message_dialog(toplevel
, "disbandnodialog", buf
,
567 unitdisband_callback_no
, 0, 0,
573 /****************************************************************
574 Parameters after named parameters should be in triplets:
575 - callback, callback_data, fixed_width
576 *****************************************************************/
577 Widget
popup_message_dialog(Widget parent
, const char *dialogname
,
578 const char *text
, ...)
581 Widget dshell
, dform
, button
;
583 Dimension width
, height
;
584 void (*fcb
)(Widget
, XtPointer
, XtPointer
);
585 XtPointer client_data
;
586 char button_name
[512];
589 XtSetSensitive(parent
, FALSE
);
591 I_T(dshell
=XtCreatePopupShell(dialogname
, transientShellWidgetClass
,
594 dform
=XtVaCreateManagedWidget("dform", formWidgetClass
, dshell
, NULL
);
596 /* caller should i18n text as desired */
597 XtVaCreateManagedWidget("dlabel", labelWidgetClass
, dform
,
598 XtNlabel
, (XtArgVal
)text
,
602 va_start(args
, text
);
604 while((fcb
=((void(*)(Widget
, XtPointer
, XtPointer
))(va_arg(args
, void *))))) {
605 client_data
=va_arg(args
, XtPointer
);
606 fixed_width
=va_arg(args
, int);
607 fc_snprintf(button_name
, sizeof(button_name
), "button%d", i
++);
609 button
=XtVaCreateManagedWidget(button_name
, commandWidgetClass
,
616 XtAddCallback(button
, XtNcallback
, fcb
, client_data
);
621 XtVaGetValues(parent
, XtNwidth
, &width
, XtNheight
, &height
, NULL
);
622 XtTranslateCoords(parent
, (Position
) width
/10, (Position
) height
/10,
624 XtVaSetValues(dshell
, XtNx
, x
, XtNy
, y
, NULL
);
626 XtPopup(dshell
, XtGrabNone
);
631 /****************************************************************
633 *****************************************************************/
634 void destroy_message_dialog(Widget button
)
636 XtSetSensitive(XtParent(XtParent(XtParent(button
))), TRUE
);
638 XtDestroyWidget(XtParent(XtParent(button
)));
641 static int number_of_columns(int n
)
644 /* This would require libm, which isn't worth it for this one little
645 * function. Since MAX_SELECT_UNITS is 100 already, the ifs
647 double sqrt(); double ceil();
648 return ceil(sqrt((double)n
/5.0));
650 fc_assert(MAX_SELECT_UNITS
== 100);
652 else if(n
<=20) return 2;
653 else if(n
<=45) return 3;
654 else if(n
<=80) return 4;
658 static int number_of_rows(int n
)
660 int c
=number_of_columns(n
);
664 /****************************************************************
665 popup the dialog 10% inside the main-window
666 *****************************************************************/
667 void unit_select_dialog_popup(struct tile
*ptile
)
673 Widget unit_select_all_command
, unit_select_close_command
;
674 Widget firstcolumn
=0,column
=0;
676 struct unit
*unit_list
[unit_list_size(ptile
->units
)];
678 XtSetSensitive(main_form
, FALSE
);
680 unit_select_dialog_shell
=
681 I_T(XtCreatePopupShell("unitselectdialogshell",
682 transientShellWidgetClass
,
685 unit_select_form
= XtVaCreateManagedWidget("unitselectform",
687 unit_select_dialog_shell
, NULL
);
689 XtVaGetValues(unit_select_form
, XtNbackground
, &bg
, NULL
);
690 XSetForeground(display
, fill_bg_gc
, bg
);
692 n
= MIN(MAX_SELECT_UNITS
, unit_list_size(ptile
->units
));
693 r
= number_of_rows(n
);
695 fill_tile_unit_list(ptile
, unit_list
);
697 for (i
= 0; i
< n
; i
++) {
698 struct unit
*punit
= unit_list
[i
];
699 struct unit_type
*punittemp
= unit_type_get(punit
);
706 XtSetArg(args
[nargs
], XtNfromHoriz
, column
);
709 column
= XtCreateManagedWidget("column", formWidgetClass
,
713 firstcolumn
= column
;
717 unit_select_ids
[i
]=punit
->id
;
719 pcity
= player_city_by_number(client_player(), punit
->homecity
);
721 fc_snprintf(buffer
, sizeof(buffer
), "%s(%s)\n%s",
722 utype_name_translation(punittemp
),
723 pcity
? city_name_get(pcity
) : "",
724 unit_activity_text(punit
));
726 unit_select_pixmaps
[i
]=XCreatePixmap(display
, XtWindow(map_canvas
),
727 tileset_full_tile_width(tileset
), tileset_full_tile_height(tileset
),
730 XFillRectangle(display
, unit_select_pixmaps
[i
], fill_bg_gc
,
731 0, 0, tileset_full_tile_width(tileset
), tileset_full_tile_height(tileset
));
732 store
.pixmap
= unit_select_pixmaps
[i
];
733 put_unit(punit
, &store
, 1.0, 0, 0);
736 XtSetArg(args
[nargs
], XtNbitmap
, (XtArgVal
)unit_select_pixmaps
[i
]);nargs
++;
737 XtSetArg(args
[nargs
], XtNsensitive
,
738 can_unit_do_activity(punit
, ACTIVITY_IDLE
));nargs
++;
740 XtSetArg(args
[nargs
], XtNfromVert
, unit_select_commands
[i
-1]); nargs
++;
742 unit_select_commands
[i
]=XtCreateManagedWidget("unitselectcommands",
744 column
, args
, nargs
);
747 XtSetArg(args
[nargs
], XtNlabel
, (XtArgVal
)buffer
); nargs
++;
748 XtSetArg(args
[nargs
], XtNfromHoriz
, unit_select_commands
[i
]); nargs
++;
750 XtSetArg(args
[nargs
], XtNfromVert
, unit_select_commands
[i
-1]); nargs
++;
752 unit_select_labels
[i
]=XtCreateManagedWidget("unitselectlabels",
754 column
, args
, nargs
);
756 XtAddCallback(unit_select_commands
[i
],
757 XtNdestroyCallback
,free_bitmap_destroy_callback
, NULL
);
758 XtAddCallback(unit_select_commands
[i
],
759 XtNcallback
, unit_select_callback
, NULL
);
764 unit_select_close_command
=
765 I_L(XtVaCreateManagedWidget("unitselectclosecommand",
768 XtNfromVert
, firstcolumn
,
771 unit_select_all_command
=
772 I_L(XtVaCreateManagedWidget("unitselectallcommand",
775 XtNfromVert
, firstcolumn
,
778 XtAddCallback(unit_select_close_command
, XtNcallback
, unit_select_callback
, NULL
);
779 XtAddCallback(unit_select_all_command
, XtNcallback
, unit_select_all_callback
, NULL
);
781 xaw_set_relative_position(toplevel
, unit_select_dialog_shell
, 15, 10);
782 XtPopup(unit_select_dialog_shell
, XtGrabNone
);
785 /**************************************************************************
786 Update the dialog window to select units on a particular tile.
787 **************************************************************************/
788 void unit_select_dialog_update_real(void)
793 /**************************************************************************
795 **************************************************************************/
796 void unit_select_all_callback(Widget w
, XtPointer client_data
,
801 XtSetSensitive(main_form
, TRUE
);
802 XtDestroyWidget(unit_select_dialog_shell
);
804 for(i
=0; i
<unit_select_no
; i
++) {
805 struct unit
*punit
= player_unit_by_number(client_player(),
808 unit_focus_set(punit
);
813 /**************************************************************************
815 **************************************************************************/
816 void unit_select_callback(Widget w
, XtPointer client_data
,
821 XtSetSensitive(main_form
, TRUE
);
822 XtDestroyWidget(unit_select_dialog_shell
);
824 for(i
=0; i
<unit_select_no
; i
++) {
826 if(unit_select_commands
[i
]==w
) {
827 struct unit
*punit
= player_unit_by_number(client_player(),
830 unit_focus_set(punit
);
838 /****************************************************************
839 popup the dialog 5% inside the main-window
840 *****************************************************************/
841 void popup_races_dialog(struct player
*pplayer
)
844 Dimension width
, height
;
846 XtSetSensitive(main_form
, FALSE
);
848 if (!races_dialog_shell
) {
849 create_races_dialog(pplayer
);
852 XtVaGetValues(toplevel
, XtNwidth
, &width
, XtNheight
, &height
, NULL
);
854 XtTranslateCoords(toplevel
, (Position
) width
/20, (Position
) height
/20,
856 XtVaSetValues(races_dialog_shell
, XtNx
, x
, XtNy
, y
, NULL
);
858 XtPopup(races_dialog_shell
, XtGrabNone
);
859 XtSetKeyboardFocus(toplevel
, races_dialog_shell
);
862 /****************************************************************
864 *****************************************************************/
865 void popdown_races_dialog(void)
867 if (races_dialog_shell
) {
868 XtSetSensitive(main_form
, TRUE
);
869 XtDestroyWidget(races_dialog_shell
);
870 races_dialog_shell
= NULL
;
871 } /* else there is no dialog shell to destroy */
874 /****************************************************************
876 *****************************************************************/
877 void create_races_dialog(struct player
*pplayer
)
880 int i
, j
, len
, maxracelen
, index
, nat_count
;
881 char maxracename
[MAX_LEN_NAME
];
884 XtWidgetGeometry geom
;
886 races_player
= pplayer
;
888 nations_iterate(pnation
) {
889 if (is_nation_playable(pnation
) && is_nation_pickable(pnation
)) {
890 len
= strlen(nation_adjective_translation(pnation
));
891 maxracelen
= MAX(maxracelen
, len
);
893 } nations_iterate_end
;
894 maxracelen
= MIN(maxracelen
, MAX_LEN_NAME
-1);
895 fc_snprintf(maxracename
, sizeof(maxracename
), "%*s", maxracelen
+2, "W");
897 races_dialog_shell
= I_T(XtCreatePopupShell("racespopup",
898 transientShellWidgetClass
,
901 races_form
= XtVaCreateManagedWidget("racesform",
903 races_dialog_shell
, NULL
);
905 races_label
= I_L(XtVaCreateManagedWidget("raceslabel",
909 races_toggles_viewport
=
910 XtVaCreateManagedWidget("racestogglesviewport",
913 XtNfromVert
, races_label
,
917 XtVaCreateManagedWidget("racestogglesform",
919 races_toggles_viewport
,
923 races_toggles
= fc_calloc(nation_count(), sizeof(Widget
));
924 free(races_toggles_to_nations
);
925 races_toggles_to_nations
= fc_calloc(nation_count(),
926 sizeof(struct nation_type
*));
931 nations_iterate(pnation
) {
932 if (!is_nation_playable(pnation
) || !is_nation_pickable(pnation
)) {
938 fc_snprintf(namebuf
, sizeof(namebuf
), "racestoggle%d", index
);
940 races_toggles
[index
] =
941 XtVaCreateManagedWidget(namebuf
,
944 XtNlabel
, maxracename
,
947 races_toggles
[index
] =
948 XtVaCreateManagedWidget(namebuf
,
952 races_toggles
[index
- 1],
954 races_toggles
[index
- per_row
],
955 XtNlabel
, maxracename
,
959 index
= i
* per_row
+ j
;
960 fc_snprintf(namebuf
, sizeof(namebuf
), "racestoggle%d", index
);
962 races_toggles
[index
] =
963 XtVaCreateManagedWidget(namebuf
,
967 races_toggles
[index
- 1],
969 races_toggles
[index
- 1],
970 XtNlabel
, maxracename
,
973 races_toggles
[index
] =
974 XtVaCreateManagedWidget(namebuf
,
978 races_toggles
[index
- 1],
980 races_toggles
[index
- per_row
],
982 races_toggles
[index
- 1],
983 XtNlabel
, maxracename
,
988 races_toggles_to_nations
[index
] = pnation
;
995 } nations_iterate_end
;
996 nat_count
= index
+ 1;
999 XtVaCreateManagedWidget("racesleaderform",
1002 XtNfromVert
, races_toggles_viewport
,
1003 /* XtNfromHoriz, races_toggles_viewport,*/
1006 XtVaGetValues(races_leader_form
, XtNdefaultDistance
, &space
, NULL
);
1007 XtQueryGeometry(races_toggles
[0], NULL
, &geom
);
1009 XtVaCreateManagedWidget("racesleader",
1010 asciiTextWidgetClass
,
1012 XtNeditType
, XawtextEdit
,
1014 space
+ 2*(geom
.width
+ geom
.border_width
),
1018 races_leader_pick_popupmenu
= 0;
1020 races_leader_pick_menubutton
=
1021 I_L(XtVaCreateManagedWidget("racesleaderpickmenubutton",
1022 menuButtonWidgetClass
,
1024 /* XtNfromVert, races_leader,*/
1025 XtNfromHoriz
, races_leader
,
1028 races_sex_label
= I_L(XtVaCreateManagedWidget("racessexlabel",
1031 XtNfromVert
, races_leader_form
,
1034 races_sex_form
= XtVaCreateManagedWidget("racessexform",
1037 XtNfromVert
, races_sex_label
,
1040 races_sex_toggles
[0] =
1041 I_L(XtVaCreateManagedWidget("racessextoggle0",
1046 races_sex_toggles
[1] =
1047 I_L(XtVaCreateManagedWidget("racessextoggle1",
1051 (XtArgVal
)races_sex_toggles
[0],
1053 races_sex_toggles
[0],
1056 /* find out styles that can be used at the game beginning */
1057 /* Limit of 64 city_styles should be deleted. -ev */
1058 styles_iterate(pstyle
) {
1059 i
= basic_city_style_for_style(pstyle
);
1062 int sn
= style_number(pstyle
);
1064 city_style_idx
[sn
] = i
;
1065 city_style_ridx
[i
] = sn
;
1067 } styles_iterate_end
;
1070 I_L(XtVaCreateManagedWidget("racesstylelabel",
1073 XtNfromVert
, races_sex_form
,
1074 /* XtNfromHoriz, races_toggles_viewport,*/
1078 XtVaCreateManagedWidget("racesstyleform",
1081 XtNfromVert
, races_style_label
,
1082 /* XtNfromHoriz, races_toggles_viewport,*/
1085 free(races_style_toggles
);
1086 races_style_toggles
= fc_calloc(game
.control
.num_styles
, sizeof(Widget
));
1088 for (i
= 0; i
< ((game
.control
.num_styles
- 1) / per_row
) + 1; i
++) {
1089 index
= i
* per_row
;
1090 fc_snprintf(namebuf
, sizeof(namebuf
), "racesstyle%d", index
);
1093 races_style_toggles
[index
] =
1094 XtVaCreateManagedWidget(namebuf
,
1097 XtNlabel
, maxracename
,
1100 races_style_toggles
[index
] =
1101 XtVaCreateManagedWidget(namebuf
,
1105 races_style_toggles
[index
-1],
1107 races_style_toggles
[index
-per_row
],
1108 XtNlabel
, maxracename
,
1112 for( j
= 1; j
< per_row
; j
++) {
1113 index
= i
* per_row
+ j
;
1114 if (index
>= game
.control
.num_styles
) {
1117 fc_snprintf(namebuf
, sizeof(namebuf
), "racesstyle%d", index
);
1119 races_style_toggles
[index
] =
1120 XtVaCreateManagedWidget(namebuf
,
1124 races_style_toggles
[index
-1],
1126 races_style_toggles
[index
-1],
1127 XtNlabel
, maxracename
,
1130 races_style_toggles
[index
] =
1131 XtVaCreateManagedWidget(namebuf
,
1135 races_style_toggles
[index
-1],
1137 races_style_toggles
[index
-per_row
],
1139 races_style_toggles
[index
-1],
1140 XtNlabel
, maxracename
,
1146 races_action_form
= XtVaCreateManagedWidget("racesactionform",
1149 XtNfromVert
, races_style_form
,
1153 I_L(XtVaCreateManagedWidget("racesokcommand",
1158 races_random_command
=
1159 I_L(XtVaCreateManagedWidget("racesdisconnectcommand",
1162 XtNfromHoriz
, races_ok_command
,
1165 races_quit_command
=
1166 I_L(XtVaCreateManagedWidget("racesquitcommand",
1169 XtNfromHoriz
, races_random_command
,
1172 XtAddCallback(races_random_command
, XtNcallback
,
1173 races_random_command_callback
, NULL
);
1174 XtAddCallback(races_quit_command
, XtNcallback
,
1175 races_quit_command_callback
, NULL
);
1178 for (i
= 0; i
< nation_count(); i
++) {
1179 if (races_toggles
[i
]) {
1180 XtAddCallback(races_toggles
[i
], XtNcallback
,
1181 races_toggles_callback
, INT_TO_XTPOINTER(i
));
1186 XtAddCallback(races_ok_command
, XtNcallback
,
1187 races_ok_command_callback
, NULL
);
1190 XtSetKeyboardFocus(races_form
, races_leader
);
1192 XtRealizeWidget(races_dialog_shell
);
1194 /* for(i=0; i<game.control.playable_nation_count; i++) {
1195 races_toggles_to_nations[i] = i;
1198 qsort(races_toggles_to_nations
, nat_count
,
1199 sizeof(struct nation_type
*), races_indirect_compare
);
1201 /* Build nation_to_race_toggle */
1202 free(nation_idx_to_race_toggle
);
1203 nation_idx_to_race_toggle
=
1204 fc_calloc(nation_count(), sizeof(int));
1205 for (i
= 0; i
< nation_count(); i
++) {
1206 nation_idx_to_race_toggle
[i
] = -1;
1208 for (i
= 0; i
< nation_count(); i
++) {
1209 if (races_toggles_to_nations
[i
]) {
1210 nation_idx_to_race_toggle
[nation_index(races_toggles_to_nations
[i
])] = i
;
1214 for (i
= 0; i
< nation_count(); i
++) {
1215 if (races_toggles
[i
]) {
1216 XtVaSetValues(races_toggles
[i
],
1218 (XtArgVal
)nation_adjective_translation(races_toggles_to_nations
[i
]),
1223 for (i
= 0; i
< game
.control
.num_styles
; i
++) {
1224 XtVaSetValues(races_style_toggles
[i
], XtNlabel
,
1225 (XtArgVal
)city_style_name_translation(city_style_idx
[i
]), NULL
);
1228 select_random_race();
1231 /****************************************************************
1233 *****************************************************************/
1234 void racesdlg_key_ok(Widget w
)
1236 Widget ok
= XtNameToWidget(XtParent(XtParent(w
)), "*racesokcommand");
1238 x_simulate_button_click(ok
);
1241 /**************************************************************************
1242 The server has changed the set of selectable nations.
1243 **************************************************************************/
1244 void races_update_pickable(bool nationset_change
)
1246 /* FIXME handle this properly */
1247 popdown_races_dialog();
1250 /**************************************************************************
1252 **************************************************************************/
1253 void races_toggles_set_sensitive(void)
1257 if (!races_dialog_shell
) {
1260 for (i
= 0; i
< nation_count(); i
++) {
1261 if (nation_idx_to_race_toggle
[i
] > -1) {
1262 XtSetSensitive(races_toggles
[nation_idx_to_race_toggle
[i
]], TRUE
);
1266 nations_iterate(nation
) {
1267 int selected_nation
= -1;
1268 int this_index
= nation_index(nation
);
1270 if (!is_nation_playable(nation
)) {
1274 if (is_nation_pickable(nation
) && !nation
->player
) {
1278 if (races_buttons_get_current() != -1) {
1280 nation_index(races_toggles_to_nations
[races_buttons_get_current()]);
1283 log_debug(" [%d]: %d = %s", selected_nation
,
1284 nation_number(nation
), nation_rule_name(nation
));
1286 if (this_index
== selected_nation
) {
1287 XawToggleUnsetCurrent(races_toggles
[0]);
1288 XtSetSensitive(races_toggles
[nation_idx_to_race_toggle
[this_index
]], FALSE
);
1289 select_random_race();
1291 XtSetSensitive(races_toggles
[nation_idx_to_race_toggle
[this_index
]], FALSE
);
1293 } nations_iterate_end
;
1296 /* We store this value locally in case it changes globally. */
1297 static int local_nation_count
;
1299 /**************************************************************************
1301 **************************************************************************/
1302 void races_toggles_callback(Widget w
, XtPointer client_data
,
1303 XtPointer call_data
)
1305 int index
= XTPOINTER_TO_INT(client_data
);
1306 struct nation_type
*race
= races_toggles_to_nations
[index
];
1310 if(races_leader_pick_popupmenu
)
1311 XtDestroyWidget(races_leader_pick_popupmenu
);
1313 races_leader_pick_popupmenu
=
1314 XtVaCreatePopupShell("menu",
1315 simpleMenuWidgetClass
,
1316 races_leader_pick_menubutton
,
1319 local_nation_count
= nation_count();
1322 nation_leader_list_iterate(nation_leaders(race
), pleader
) {
1324 XtVaCreateManagedWidget(nation_leader_name(pleader
),
1326 races_leader_pick_popupmenu
,
1328 XtAddCallback(entry
, XtNcallback
, races_leader_pick_callback
,
1329 INT_TO_XTPOINTER(local_nation_count
* j
1330 + nation_index(race
)));
1332 } nation_leader_list_iterate_end
;
1334 races_leader_set_values(race
, fc_rand(j
));
1336 x_simulate_button_click
1338 races_style_toggles
[city_style_ridx
[style_number(style_of_nation(race
))]]
1342 /**************************************************************************
1344 **************************************************************************/
1345 void races_leader_pick_callback(Widget w
, XtPointer client_data
,
1346 XtPointer call_data
)
1348 int lead
= XTPOINTER_TO_INT(client_data
) / local_nation_count
;
1349 int race
= XTPOINTER_TO_INT(client_data
) - (local_nation_count
* lead
);
1351 races_leader_set_values(nation_by_number(race
), lead
);
1354 /**************************************************************************
1356 **************************************************************************/
1357 void races_leader_set_values(struct nation_type
*race
, int lead
)
1359 const struct nation_leader
*pleader
=
1360 nation_leader_list_get(nation_leaders(race
), lead
);
1362 XtVaSetValues(races_leader
, XtNstring
, nation_leader_name(pleader
), NULL
);
1363 XawTextSetInsertionPoint(races_leader
,
1364 strlen(nation_leader_name(pleader
)));
1366 races_sex_buttons_set_current(!nation_leader_is_male(pleader
));
1369 /**************************************************************************
1371 **************************************************************************/
1372 int races_buttons_get_current(void)
1377 if (nation_count() == 1) {
1381 if(!(dp
=XawToggleGetCurrent(races_toggles
[0])))
1384 for(i
= 0; i
< nation_count(); i
++) {
1385 if (races_toggles
[i
]) {
1386 XtVaGetValues(races_toggles
[i
], XtNradioData
, &yadp
, NULL
);
1395 /**************************************************************************
1397 **************************************************************************/
1398 int races_sex_buttons_get_current(void)
1403 if(!(dp
=XawToggleGetCurrent(races_sex_toggles
[0])))
1406 for(i
=0; i
<2; i
++) {
1407 XtVaGetValues(races_sex_toggles
[i
], XtNradioData
, &yadp
, NULL
);
1415 /**************************************************************************
1417 **************************************************************************/
1418 int races_style_buttons_get_current(void)
1423 if (game
.control
.num_styles
== 1) {
1427 if(!(dp
=XawToggleGetCurrent(races_style_toggles
[0])))
1430 for (i
= 0; i
< game
.control
.num_styles
; i
++) {
1431 XtVaGetValues(races_style_toggles
[i
], XtNradioData
, &yadp
, NULL
);
1440 /**************************************************************************
1442 **************************************************************************/
1443 void races_sex_buttons_set_current(int i
)
1447 XtVaGetValues(races_sex_toggles
[i
], XtNradioData
, &dp
, NULL
);
1449 XawToggleSetCurrent(races_sex_toggles
[0], dp
);
1452 /**************************************************************************
1454 **************************************************************************/
1455 int races_indirect_compare(const void *first
, const void *second
)
1457 const char *first_string
;
1458 const char *second_string
;
1460 struct nation_type
*first_nation
= *(struct nation_type
**)first
;
1461 struct nation_type
*second_nation
= *(struct nation_type
**)second
;
1463 first_string
= nation_adjective_translation(first_nation
);
1464 second_string
= nation_adjective_translation(second_nation
);
1466 return fc_strcasecmp(first_string
, second_string
);
1469 /**************************************************************************
1471 **************************************************************************/
1472 void races_ok_command_callback(Widget w
, XtPointer client_data
,
1473 XtPointer call_data
)
1475 int selected_index
, selected_sex
, selected_style
;
1478 if((selected_index
=races_buttons_get_current())==-1) {
1479 output_window_append(ftc_client
, _("You must select a nation."));
1483 if((selected_sex
=races_sex_buttons_get_current())==-1) {
1484 output_window_append(ftc_client
, _("You must select your sex."));
1488 if ((selected_style
= races_style_buttons_get_current()) == -1) {
1489 output_window_append(ftc_client
, _("You must select your style."));
1493 XtVaGetValues(races_leader
, XtNstring
, &dp
, NULL
);
1495 /* perform a minimum of sanity test on the name */
1496 if (strlen(dp
) == 0) {
1497 output_window_append(ftc_client
, _("You must type a legal name."));
1501 dsend_packet_nation_select_req(&client
.conn
,
1502 player_number(races_player
),
1503 nation_index(races_toggles_to_nations
[selected_index
]),
1504 selected_sex
? FALSE
: TRUE
,
1506 city_style_idx
[selected_style
]);
1507 popdown_races_dialog();
1510 /**************************************************************************
1512 **************************************************************************/
1513 void races_random_command_callback(Widget w
, XtPointer client_data
,
1514 XtPointer call_data
)
1516 popdown_races_dialog();
1517 /* disconnect_from_server();*/
1520 /**************************************************************************
1522 **************************************************************************/
1523 void races_quit_command_callback(Widget w
, XtPointer client_data
,
1524 XtPointer call_data
)
1529 /**************************************************************************
1530 Frees a bitmap associated with a Widget when it is destroyed
1531 **************************************************************************/
1532 void free_bitmap_destroy_callback(Widget w
, XtPointer client_data
,
1533 XtPointer call_data
)
1537 XtVaGetValues(w
,XtNbitmap
,&pm
,NULL
);
1538 if(pm
) XFreePixmap(XtDisplay(w
),pm
);
1541 /**************************************************************************
1542 Destroys its widget. Usefull for a popdown callback on pop-ups that
1544 **************************************************************************/
1545 void destroy_me_callback(Widget w
, XtPointer client_data
,
1546 XtPointer call_data
)
1551 /**************************************************************************
1552 Adjust tax rates from main window
1553 **************************************************************************/
1554 void taxrates_callback(Widget w
, XtPointer client_data
, XtPointer call_data
)
1556 common_taxrates_callback((size_t) client_data
);
1559 /**************************************************************************
1560 Ruleset (modpack) has suggested loading certain tileset. Confirm from
1562 **************************************************************************/
1563 void popup_tileset_suggestion_dialog(void)
1567 /****************************************************************
1568 Ruleset (modpack) has suggested loading certain soundset. Confirm from
1570 *****************************************************************/
1571 void popup_soundset_suggestion_dialog(void)
1575 /****************************************************************
1576 Ruleset (modpack) has suggested loading certain musicset. Confirm from
1578 *****************************************************************/
1579 void popup_musicset_suggestion_dialog(void)
1583 /**************************************************************************
1584 Tileset (modpack) has suggested loading certain theme. Confirm from
1586 **************************************************************************/
1587 bool popup_theme_suggestion_dialog(const char *theme_name
)
1593 /**********************************************************************
1594 This function is called when the client disconnects or the game is
1595 over. It should close all dialog windows for that game.
1596 ***********************************************************************/
1597 void popdown_all_game_dialogs(void)
1599 city_report_dialog_popdown();
1600 meswin_dialog_popdown();
1601 science_report_dialog_popdown();
1602 economy_report_dialog_popdown();
1603 units_report_dialog_popdown();
1604 popdown_players_dialog();
1605 popdown_notify_dialog();
1608 /****************************************************************
1609 Player has gained a new tech.
1610 *****************************************************************/
1611 void show_tech_gained_dialog(Tech_type_id tech
)
1616 /****************************************************************
1617 Show tileset error dialog.
1618 *****************************************************************/
1619 void show_tileset_error(const char *msg
)
1624 /****************************************************************
1625 Give a warning when user is about to edit scenario with manually
1627 *****************************************************************/
1628 bool handmade_scenario_warning(void)
1630 /* Just tell the client common code to handle this. */
1634 /****************************************************************
1635 Unit wants to get into some transport on given tile.
1636 *****************************************************************/
1637 bool request_transport(struct unit
*pcargo
, struct tile
*ptile
)
1639 return FALSE
; /* Unit was not handled here. */