1 /**********************************************************************
2 *
3 * FreeDoko a Doppelkopf-Game
4 *
5 * Copyright (C) 2001 – 2018 by Diether Knof and Borg Enders
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; either version 2 of
10 * the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 * You can find this license in the file 'gpl.txt'.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21 * MA 02111-1307 USA
22 *
23 * Contact:
24 * Diether Knof dknof@posteo.de
25 *
26 *********************************************************************/
27
28 #include "constants.h"
29
30 #ifdef USE_UI_GTKMM
31
32 #include "party_settings.h"
33 #include "players.h"
34 #include "rules.h"
35
36 #include "ui.h"
37 #include "main_window.h"
38 #include "bug_report.h"
39 #include "first_run.h"
40 #include "program_updated.h"
41
42 #include "../../party/party.h"
43 #include "../../player/player.h"
44 #include "../../player/aiconfig.h"
45 #include "../../os/bug_report_replay.h"
46 #include "../../misc/preferences.h"
47 #include "../../utils/random.h"
48
49 #include <gtkmm/radiobutton.h>
50 #include <gtkmm/spinbutton.h>
51 #include <gtkmm/frame.h>
52 #include <gtkmm/main.h>
53 #include <gtkmm/grid.h>
54 #include <gtkmm/filechooserdialog.h>
55 namespace UI_GTKMM_NS {
56
57 /** constructor
58 **
59 ** @param parent the parent object
60 **/
PartySettings(Base * const parent)61 PartySettings::PartySettings(Base* const parent) :
62 Base(parent),
63 StickyDialog("FreeDoko – " + _("Window::party settings"),
64 *parent->ui->main_window, false)
65 {
66 this->ui->add_window(*this);
67
68 this->init();
69
70 this->signal_show().connect(sigc::mem_fun(*this, &PartySettings::update));
71 this->signal_key_press_event().connect(sigc::mem_fun(*this,
72 &PartySettings::key_press));
73
74 this->ui->bug_report->set_dnd_destination(*this);
75 } // PartySettings::PartySettings(Base* parent)
76
77 /** destruktor
78 **/
79 PartySettings::~PartySettings() = default;
80
81 /** create all subelements
82 **/
83 void
init()84 PartySettings::init()
85 {
86 #ifdef POSTPONED
87 auto& party = this->ui->party();
88 #else
89 auto& party = *::party;
90 #endif
91
92 this->set_icon(this->ui->icon);
93
94 this->set_position(Gtk::WIN_POS_CENTER_ON_PARENT);
95
96 this->players = make_unique<Players>(this);
97 this->rules = make_unique<Rules>(this);
98
99 this->load_bug_report_button
100 = Gtk::manage(new Gtk::Button(_("Button::load bug report")));
101 this->load_bug_report_button->set_image_from_icon_name("document-open");
102 this->load_bug_report_button->set_always_show_image();
103 #ifndef RELEASE
104 this->add_action_widget(*this->load_bug_report_button,
105 Gtk::RESPONSE_NONE);
106 #endif
107 this->start_party_button
108 = Gtk::manage(new Gtk::Button(_("Button::start party")));
109 this->add_action_widget(*this->start_party_button, Gtk::RESPONSE_CLOSE);
110 this->start_party_button->set_can_default();
111
112 this->close_button = add_close_button(*this);
113
114 { // seed
115 this->seed_value = Gtk::manage(new Gtk::SpinButton(1, 0));
116 this->seed_value->set_value(0);
117 this->seed_value->set_range(0, Random::max_seed());
118 this->seed_value->set_increments(1, 1000);
119 this->seed_random = Gtk::manage(new Gtk::CheckButton(_("Button::random")));
120 } // seed
121 { // duration
122 this->rule_number_of_rounds_limited
123 = Gtk::manage(new Gtk::CheckButton(_(Rule::Type::number_of_rounds) + ":"));
124 this->rule_number_of_rounds
125 = Gtk::manage(new Gtk::SpinButton());
126 this->rule_number_of_rounds->set_increments(1, 10);
127 this->rule_points_limited
128 = Gtk::manage(new Gtk::CheckButton(_(Rule::Type::points) + ":"));
129 this->rule_points
130 = Gtk::manage(new Gtk::SpinButton());
131 this->rule_points->set_increments(1, 10);
132 } // duration
133 { // startplayer
134 this->startplayer_random = Gtk::manage(new Gtk::RadioButton(_("Button::random")));
135 } // startplayer
136
137 this->configure_players
138 = Gtk::manage(new Gtk::Button(_("Button::configure players")));
139 this->configure_players->set_image_from_icon_name("face-smile");
140 this->configure_players->set_always_show_image();
141 this->configure_rules
142 = Gtk::manage(new Gtk::Button(_("Button::configure rules")));
143 this->configure_rules->set_image_from_icon_name("preferences-other");
144 this->configure_rules->set_always_show_image();
145
146
147 { // create the startplayer buttons
148 auto startplayer_group
149 = this->startplayer_random->get_group();
150 for (auto const& p : party.players()) {
151 this->startplayer.push_back(Gtk::manage(new Gtk::RadioButton(startplayer_group, p.name())));
152 }
153 { // the swap buttons
154 #ifdef WORKAROUND
155 // MS-Windows does not show the arrows
156 #include "arrows/arrow_lu.xpm"
157 #include "arrows/arrow_ur.xpm"
158 #include "arrows/arrow_rd.xpm"
159 #include "arrows/arrow_dl.xpm"
160 this->swap_players_buttons.push_back(Gtk::manage(new Gtk::Button()));
161 this->swap_players_buttons.back()->add(*Gtk::manage(new Gtk::Image(Gdk::Pixbuf::create_from_xpm_data(arrow_lu_xpm))));
162 this->swap_players_buttons.push_back(Gtk::manage(new Gtk::Button()));
163 this->swap_players_buttons.back()->add(*Gtk::manage(new Gtk::Image(Gdk::Pixbuf::create_from_xpm_data(arrow_ur_xpm))));
164 this->swap_players_buttons.push_back(Gtk::manage(new Gtk::Button()));
165 this->swap_players_buttons.back()->add(*Gtk::manage(new Gtk::Image(Gdk::Pixbuf::create_from_xpm_data(arrow_rd_xpm))));
166 this->swap_players_buttons.push_back(Gtk::manage(new Gtk::Button()));
167 this->swap_players_buttons.back()->add(*Gtk::manage(new Gtk::Image(Gdk::Pixbuf::create_from_xpm_data(arrow_dl_xpm))));
168
169 for (auto& b : this->swap_players_buttons)
170 b->set_relief(Gtk::RELIEF_NONE);
171 #else
172 this->swap_players_buttons.push_back(Gtk::manage(new Gtk::Button(Glib::ustring(1, static_cast<gunichar>(0x2196))))); // up left
173 this->swap_players_buttons.push_back(Gtk::manage(new Gtk::Button(Glib::ustring(1, static_cast<gunichar>(0x2197))))); // up right
174 this->swap_players_buttons.push_back(Gtk::manage(new Gtk::Button(Glib::ustring(1, static_cast<gunichar>(0x2199))))); // down right
175 this->swap_players_buttons.push_back(Gtk::manage(new Gtk::Button(Glib::ustring(1, static_cast<gunichar>(0x2198))))); // down left
176 #endif
177 } // the swap buttons
178 } // create the startplayer buttons
179 { // Layout
180 auto hbox = Gtk::manage(new Gtk::Box());
181 hbox->set_spacing(1 EM);
182 hbox->set_border_width(1 EM);
183 this->get_content_area()->add(*hbox);
184 { // actions
185 { // configure
186 auto vbox = Gtk::manage(new Gtk::Box(Gtk::ORIENTATION_VERTICAL, 1 EX));
187 vbox->set_homogeneous();
188 vbox->set_halign(Gtk::ALIGN_CENTER);
189 vbox->set_valign(Gtk::ALIGN_CENTER);
190
191 vbox->add(*this->configure_rules);
192 vbox->add(*this->configure_players);
193 hbox->pack_end(*vbox, false, true);
194 } // configure
195
196 } // actions
197
198 { // settings
199 auto vbox = Gtk::manage(new Gtk::Box(Gtk::ORIENTATION_VERTICAL, 1 EX));
200 vbox->set_halign(Gtk::ALIGN_CENTER);
201 vbox->set_valign(Gtk::ALIGN_CENTER);
202
203 { // seed
204 this->seed_frame = Gtk::manage(new Gtk::Frame(_("card distribution")));
205 auto grid = Gtk::manage(new Gtk::Grid());
206
207 grid->set_halign(Gtk::ALIGN_CENTER);
208 grid->set_border_width(2 EX);
209 grid->set_row_spacing(1 EX);
210 grid->set_column_spacing(1 EM);
211
212 auto label = Gtk::manage(new Gtk::Label(_("Label::seed") + ":"));
213 grid->attach(*label, 0, 0, 1, 1);
214 grid->attach(*this->seed_random, 1, 0, 1, 1);
215 grid->attach(*this->seed_value, 1, 1, 1, 1);
216 seed_frame->add(*grid);
217 vbox->add(*this->seed_frame);
218 } // seed
219
220 { // duration
221 auto duration_frame = Gtk::manage(new Gtk::Frame(_("party duration")));
222
223 auto grid = Gtk::manage(new Gtk::Grid());
224 grid->set_halign(Gtk::ALIGN_CENTER);
225 grid->set_border_width(2 EX);
226 grid->set_row_spacing(1 EX);
227 grid->set_column_spacing(1 EM);
228
229 grid->attach(*this->rule_number_of_rounds_limited, 0, 0, 1, 1);
230 grid->attach(*this->rule_number_of_rounds, 1, 0, 1, 1);
231 grid->attach(*this->rule_points_limited, 0, 1, 1, 1);
232 grid->attach(*this->rule_points, 1, 1, 1, 1);
233 duration_frame->add(*grid);
234 vbox->add(*duration_frame);
235 } // duration
236
237 { // startplayer
238 this->startplayer_frame
239 = Gtk::manage(new Gtk::Frame(_("startplayer")));
240 vbox->add(*this->startplayer_frame);
241
242 auto grid = Gtk::manage(new Gtk::Grid());
243 grid->set_halign(Gtk::ALIGN_CENTER);
244 grid->set_row_homogeneous(true);
245 grid->set_column_homogeneous(true);
246 grid->set_border_width(2 EX);
247 grid->set_row_spacing(1 EX);
248 grid->set_column_spacing(1 EM);
249
250 grid->attach(*this->startplayer_random, 1, 1, 1, 1);
251 grid->attach(*this->startplayer[0], 1, 2, 1, 1);
252 grid->attach(*this->startplayer[1], 0, 1, 1, 1);
253 grid->attach(*this->startplayer[2], 1, 0, 1, 1);
254 grid->attach(*this->startplayer[3], 2, 1, 1, 1);
255 grid->attach(*this->swap_players_buttons[0], 0, 2, 1, 1);
256 grid->attach(*this->swap_players_buttons[1], 0, 0, 1, 1);
257 grid->attach(*this->swap_players_buttons[2], 2, 0, 1, 1);
258 grid->attach(*this->swap_players_buttons[3], 2, 2, 1, 1);
259 this->startplayer_frame->add(*grid);
260 } // startplayer
261 hbox->pack_start(*vbox, true, true);
262 } // settings
263
264 } // Layout
265
266 { // signals
267 this->load_bug_report_button->signal_clicked().connect(sigc::mem_fun(*this,
268 &PartySettings::load_bug_report)
269 );
270 this->start_party_button->signal_clicked().connect(sigc::mem_fun(*this,
271 &PartySettings::start_party_event)
272 );
273
274 this->seed_value->signal_value_changed().connect(sigc::mem_fun(*this, &PartySettings::seed_change_event));
275 this->seed_random->signal_toggled().connect(sigc::mem_fun(*this, &PartySettings::seed_change_event));
276 this->seed_random->signal_toggled().connect(sigc::mem_fun(*this,
277 &PartySettings::seed_value_sensitivity_update)
278 );
279
280 this->rule_number_of_rounds_limited->signal_toggled().connect(sigc::bind<int const>(sigc::mem_fun(*this, &PartySettings::rule_change), Rule::Type::number_of_rounds_limited));
281 this->rule_number_of_rounds->signal_value_changed().connect(sigc::bind<int const>(sigc::mem_fun(*this, &PartySettings::rule_change), Rule::Type::number_of_rounds));
282 this->rule_points_limited->signal_toggled().connect(sigc::bind<int const>(sigc::mem_fun(*this, &PartySettings::rule_change), Rule::Type::points_limited));
283 this->rule_points->signal_value_changed().connect(sigc::bind<int const>(sigc::mem_fun(*this, &PartySettings::rule_change), Rule::Type::points));
284
285 this->startplayer_random->signal_toggled().connect(sigc::mem_fun(*this, &PartySettings::startplayer_change_event));
286 for (auto& p : this->startplayer)
287 p->signal_toggled().connect(sigc::mem_fun(*this, &PartySettings::startplayer_change_event));
288
289 for (unsigned p = 0; p < this->swap_players_buttons.size(); ++p)
290 this->swap_players_buttons[p]->signal_clicked().connect(sigc::bind<unsigned const>(sigc::mem_fun(*this, &PartySettings::swap_players_event), p));
291
292 this->configure_players->signal_clicked().connect(sigc::mem_fun0(*this->players,
293 &Gtk::Window::present)
294 );
295 this->configure_rules->signal_clicked().connect(sigc::mem_fun0(*this->rules,
296 &Gtk::Window::present)
297 );
298 } // signals
299
300 this->show_all_children();
301 this->sensitivity_update();
302 this->update();
303
304 party.signal_seed_changed().connect_back(*this, &PartySettings::update, this->disconnector_);
305 party.signal_startplayer_changed().connect_back(*this, &PartySettings::update, this->disconnector_);
306 party.rule().signal_changed().connect_back([this](auto type, auto old_value)
307 { this->rules_update();
308 this->rules->update(type); });
309 } // void PartySettings::init()
310
311 /** get the party settings
312 **/
313 void
get()314 PartySettings::get()
315 {
316 if (::fast_play & FastPlay::party_start) {
317 ::fast_play.remove(FastPlay::party_start);
318 return ;
319 }
320
321 auto& party = this->ui->party();
322 this->update();
323
324 this->players->create_backup();
325 this->rules->create_backup();
326
327 this->start_party_button->show();
328 this->start_party_button->grab_default();
329 this->start_party_button->grab_focus();
330
331 this->present();
332 this->start_party_button->grab_focus();
333
334 while ( !this->ui->thrower
335 && this->is_visible()
336 && (::game_status == GameStatus::party_new)) {
337 ::ui->wait();
338 if (::bug_report_replay
339 && ::bug_report_replay->auto_start_party())
340 break;
341 }
342
343 if (::game_status == GameStatus::party_new) {
344 // set the seed
345 if (this->seed_random->get_active()) {
346 party.set_random_seed();
347 } else {
348 party.set_seed(this->seed_value->get_value());
349 }
350
351 // set the startplayer
352 if (this->startplayer_random->get_active())
353 party.set_random_startplayer();
354 else
355 for (unsigned p = 0; p < party.players().size(); ++p)
356 if (this->startplayer[p]->get_active()) {
357 party.set_startplayer(p);
358 break;
359 }
360
361 this->players->create_backup();
362 this->rules->create_backup();
363 } // if (::game_status == GameStatus::party_new)
364
365 this->hide();
366 } // void PartySettings::get()
367
368 /** show the window.
369 ** Shows/hides the action buttons
370 **/
371 void
on_show()372 PartySettings::on_show()
373 {
374 #ifdef GLIBMM_DEFAULT_SIGNAL_HANDLERS_ENABLED
375 this->Dialog::on_show();
376 #endif
377
378 if (this->ui->first_run_window)
379 this->ui->first_run_window->raise();
380 if (this->ui->program_updated_window)
381 this->ui->program_updated_window->raise();
382
383 this->update();
384 } // void PartySettings::show()
385
386 /** load the bug report
387 **/
388 void
load_bug_report()389 PartySettings::load_bug_report()
390 {
391 this->ui->bug_report->load_file_chooser->present();
392 } // void PartySettings::load_bug_report()
393
394 /** update the sensitivity of all elements
395 **/
396 void
sensitivity_update()397 PartySettings::sensitivity_update()
398 {
399 auto sensitive = (::game_status == GameStatus::party_new);
400 if (sensitive)
401 this->seed_value_sensitivity_update();
402 else
403 this->seed_value->set_sensitive(false);
404
405 this->seed_random->set_sensitive(sensitive);
406
407 this->rule_number_of_rounds_limited->set_sensitive(sensitive);
408 this->rule_number_of_rounds->set_sensitive(sensitive);
409 this->rule_points_limited->set_sensitive(sensitive);
410 this->rule_points->set_sensitive(sensitive);
411
412 for (auto& p : this->startplayer)
413 p->set_sensitive(sensitive);
414 this->startplayer_random->set_sensitive(sensitive);
415 for (auto p : this->swap_players_buttons)
416 p->set_sensitive(sensitive);
417
418 this->players->sensitivity_update();
419 this->rules->sensitivity_update();
420
421 this->load_bug_report_button->set_sensitive(sensitive);
422 this->start_party_button->set_sensitive(sensitive);
423
424 if (::preferences(::Preferences::Type::additional_party_settings)) {
425 this->seed_frame->show();
426 this->startplayer_frame->show();
427 } else {
428 this->seed_frame->hide();
429 this->startplayer_frame->hide();
430 }
431 } // void PartySettings::sensitivity_update()
432
433 /** update the sensitivity of 'seed_value'
434 **/
435 void
seed_value_sensitivity_update()436 PartySettings::seed_value_sensitivity_update()
437 {
438 switch (::game_status) {
439 case GameStatus::party_new:
440 case GameStatus::party_initial_loaded:
441 this->seed_value->set_sensitive(!(this->seed_random->get_active()));
442 break;
443 default:
444 this->seed_value->set_sensitive(false);
445 break;
446 } // switch (::game_status);
447 } // void PartySettings::seed_value_sensitivity_update()
448
449 /** update the widgets
450 **/
451 void
update()452 PartySettings::update()
453 {
454 if (!this->is_visible())
455 return ;
456
457 auto& party = this->ui->party();
458 this->sensitivity_update();
459
460 switch (::game_status) {
461 case GameStatus::party_new:
462 #ifndef RELEASE
463 this->load_bug_report_button->show();
464 #endif
465 this->start_party_button->show();
466 this->close_button->hide();
467
468 this->start_party_button->grab_default();
469 break;
470 default:
471 this->load_bug_report_button->hide();
472 this->start_party_button->hide();
473 this->close_button->show();
474
475 this->close_button->grab_default();
476 break;
477 } // switch (::game_status)
478
479 auto const random_seed = party.random_seed();
480 if (!random_seed)
481 this->seed_value->set_value(party.seed());
482 this->seed_random->set_active(random_seed);
483
484 this->rules_update();
485
486 if (party.random_startplayer())
487 this->startplayer_random->set_active(true);
488 else
489 this->startplayer[party.startplayer()]->set_active(true);
490
491 for (auto& p : party.players()) {
492 this->name_update_local(p);
493 }
494 this->players->update();
495 this->rules->update_all();
496 } // void PartySettings::update()
497
498 /** update the rules (value, sensitivity)
499 **/
500 void
rules_update()501 PartySettings::rules_update()
502 {
503 auto const& rule = this->ui->party().rule();
504
505 this->rule_number_of_rounds_limited->set_active(rule(Rule::Type::number_of_rounds_limited));
506 this->rule_number_of_rounds_limited->set_sensitive(rule.dependencies(Rule::Type::number_of_rounds_limited));
507 this->rule_number_of_rounds->set_value(rule(Rule::Type::number_of_rounds));
508 this->rule_number_of_rounds->set_sensitive(rule(Rule::Type::number_of_rounds_limited));
509 this->rule_number_of_rounds->set_value(rule(Rule::Type::number_of_rounds));
510 {
511 auto const value = rule(Rule::Type::number_of_rounds);
512 this->rule_number_of_rounds->set_range(rule.min(Rule::Type::number_of_rounds),
513 rule.max(Rule::Type::number_of_rounds));
514 this->rule_number_of_rounds->set_value(value);
515 }
516
517 this->rule_points_limited->set_active(rule(Rule::Type::points_limited));
518 this->rule_points_limited->set_sensitive(rule.dependencies(Rule::Type::points_limited));
519 this->rule_points->set_sensitive(true);
520 this->rule_points->set_value(rule(Rule::Type::points));
521 this->rule_points->set_sensitive(rule(Rule::Type::points_limited));
522 {
523 auto const value = rule(Rule::Type::points);
524 this->rule_points->set_range(rule.min(Rule::Type::points),
525 rule.max(Rule::Type::points));
526 this->rule_points->set_value(value);
527 }
528 } // void PartySettings::rules_update()
529
530 /** the rules have been changed
531 **
532 ** @param type the type of the rule that has changed
533 **/
534 void
rule_change(int const type)535 PartySettings::rule_change(int const type)
536 {
537 auto& rule = this->ui->party().rule();
538 switch(type) {
539 case Rule::Type::number_of_rounds_limited:
540 rule.set(Rule::Type::number_of_rounds_limited,
541 this->rule_number_of_rounds_limited->get_active());
542 break;
543 case Rule::Type::number_of_rounds:
544 rule.set(Rule::Type::number_of_rounds,
545 this->rule_number_of_rounds->get_value_as_int());
546 break;
547 case Rule::Type::points_limited:
548 rule.set(Rule::Type::points_limited,
549 this->rule_points_limited->get_active());
550 break;
551 case Rule::Type::points:
552 rule.set(Rule::Type::points,
553 this->rule_points->get_value_as_int());
554 break;
555 default:
556 break;
557 } // switch(type)
558 } // void PartySettings::rule_change(int type)
559
560 /** the players 'player_a' and 'player_b' have been swapped
561 **
562 ** @param player_a first player
563 ** @param player_b second player
564 **/
565 void
players_swapped(Player const & player_a,Player const & player_b)566 PartySettings::players_swapped(Player const& player_a,
567 Player const& player_b)
568 {
569 this->name_update_local(player_a);
570 this->name_update_local(player_b);
571
572 this->players->players_swapped(player_a, player_b);
573 } // void PartySettings::players_swapped(Player player_a, Player player_b)
574
575 /** update 'player'
576 **
577 ** @param player player to update
578 **/
579 void
player_update(Player const & player)580 PartySettings::player_update(Player const& player)
581 {
582 if (::game_status <= GameStatus::party_new)
583 return ;
584
585 this->name_update_local(player);
586 this->players->player_update(player);
587 } // void PartySettings::player_update(Player player)
588
589 /** update the name of 'player'
590 **
591 ** @param player player with the new name
592 **/
593 void
name_update(Player const & player)594 PartySettings::name_update(Player const& player)
595 {
596 this->name_update_local(player);
597 this->players->name_update(player);
598 } // void PartySettings::name_update(Player const& player)
599
600 /** update the name of 'player'
601 **
602 ** @param player player with the new name
603 **/
604 void
name_update_local(Player const & player)605 PartySettings::name_update_local(Player const& player)
606 {
607 Pango::FontDescription fd;
608 fd.set_weight(player.type() == Player::Type::human
609 ? Pango::WEIGHT_BOLD
610 : Pango::WEIGHT_NORMAL);
611 auto const playerno = this->ui->party().players().no(player);
612 DEBUG_ASSERTION((playerno < UINT_MAX),
613 "PlayerSettings::name_update_local(player)\n"
614 " player '" << player.name() << "' not found in the party");
615 if (playerno >= 4)
616 return ;
617
618 this->startplayer[playerno]->get_child()->override_font(fd);
619
620 this->startplayer[playerno]->set_label(player.name());
621 } // void PartySettings::name_update_local(Player player)
622
623 /** update the voice of 'player'
624 **
625 ** @param player player with the new voice
626 **/
627 void
voice_update(Player const & player)628 PartySettings::voice_update(Player const& player)
629 {
630 this->players->voice_update(player);
631 } // void PartySettings::voice_update(Player player)
632
633 /** update the aiconfig
634 **
635 ** @param aiconfig changed aiconfig
636 **/
637 void
aiconfig_update(Aiconfig const & aiconfig)638 PartySettings::aiconfig_update(Aiconfig const& aiconfig)
639 {
640 this->players->aiconfig_update(aiconfig);
641 } // void PartySettings::aiconfig_update(Aiconfig aiconfig)
642
643 /** a new party is started
644 **/
645 void
start_party_event()646 PartySettings::start_party_event()
647 {
648 this->hide();
649 ::game_status = GameStatus::party_new;
650 } // void PartySettings::start_party_event()
651
652 /** the seed has changed
653 **/
654 void
seed_change_event()655 PartySettings::seed_change_event()
656 {
657 auto& party = this->ui->party();
658 // set the seed
659 if (this->seed_random->get_active())
660 party.set_random_seed();
661 else
662 party.set_seed(this->seed_value->get_value());
663 } // void PartySettings::seed_change_event()
664
665 /** the startplayer has changed
666 **/
667 void
startplayer_change_event()668 PartySettings::startplayer_change_event()
669 {
670 auto& party = this->ui->party();
671 // set the startplayer
672 if (this->startplayer_random->get_active())
673 party.set_random_startplayer();
674 else
675 for (unsigned p = 0; p < party.players().size(); ++p)
676 if (this->startplayer[p]->get_active()) {
677 party.set_startplayer(p);
678 break;
679 }
680 } // void PartySettings::startplayer_change_event()
681
682 /** players shall be swapped
683 **
684 ** @param p player to swap with the following
685 **/
686 void
swap_players_event(unsigned const p)687 PartySettings::swap_players_event(unsigned const p)
688 {
689 auto& party = this->ui->party();
690 party.players().swap(p, (p + 1) % party.players().size());
691 } // void PartySettings::swap_players_event(unsigned p)
692
693 /** a key has been pressed
694 **
695 ** @param key the key
696 **
697 ** @return whether the key was used
698 **/
699 bool
key_press(GdkEventKey * const key)700 PartySettings::key_press(GdkEventKey* const key)
701 {
702 bool used = false;
703
704 if ((key->state & ~GDK_SHIFT_MASK) == 0) {
705 switch (key->keyval) {
706 case GDK_KEY_p: // show the players
707 this->players->present();
708 used = true;
709 break;
710 case GDK_KEY_r: // show the rules
711 this->rules->present();
712 used = true;
713 break;
714 } // switch (key->keyval)
715 } // if ((key->state & ~GDK_SHIFT_MASK) == 0)
716
717 return (used || this->ui->key_press(key));
718 } // bool PartySettings::key_press(GdkEventKey* key)
719
720 } // namespace UI_GTKMM_NS
721
722 #endif // #ifdef USE_UI_GTKMM
723