initial commit, lordsawar source, slightly modified
[lordsawar] / src / gui / preferences-dialog.cpp
1 //  Copyright (C) 2007 Ole Laursen
2 //  Copyright (C) 2007, 2008, 2009 Ben Asselstine
3 //
4 //  This program is free software; you can redistribute it and/or modify
5 //  it under the terms of the GNU General Public License as published by
6 //  the Free Software Foundation; either version 3 of the License, or
7 //  (at your option) any later version.
8 //
9 //  This program is distributed in the hope that it will be useful,
10 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
11 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 //  GNU Library General Public License for more details.
13 //
14 //  You should have received a copy of the GNU General Public License
15 //  along with this program; if not, write to the Free Software
16 //  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 
17 //  02110-1301, USA.
18
19 #include <config.h>
20
21 #include <gtkmm.h>
22 #include <sigc++/functors/mem_fun.h>
23
24 #include "preferences-dialog.h"
25
26 #include "glade-helpers.h"
27 #include "image-helpers.h"
28 #include "ucompose.hpp"
29 #include "defs.h"
30 #include "Configuration.h"
31 #include "sound.h"
32 #include "game.h"
33 #include "playerlist.h"
34 #include "citylist.h"
35 #include "ruinlist.h"
36 #include "ai_fast.h"
37 #include "GraphicsCache.h"
38
39
40
41 PreferencesDialog::PreferencesDialog(bool readonly)
42 {
43   d_readonly = readonly;
44     Glib::RefPtr<Gtk::Builder> xml
45         = Gtk::Builder::create_from_file(get_glade_path()
46                                     + "/preferences-dialog.ui");
47
48     xml->get_widget("dialog", dialog);
49     decorate(dialog);
50     window_closed.connect(sigc::mem_fun(dialog, &Gtk::Dialog::hide));
51
52     xml->get_widget("commentator_checkbutton", commentator_checkbutton);
53     xml->get_widget("speed_scale", speed_scale);
54     xml->get_widget("play_music_checkbutton", play_music_checkbutton);
55     xml->get_widget("music_volume_scale", music_volume_scale);
56     xml->get_widget("music_volume_hbox", music_volume_hbox);
57     xml->get_widget("players_vbox", players_vbox);
58     
59     GraphicsCache *gc = GraphicsCache::getInstance();
60     for (unsigned int i = 0; i < MAX_PLAYERS; i++)
61       {
62         Player *p = Playerlist::getInstance()->getPlayer(i);
63         if (p == NULL)
64           continue;
65         if (p == Playerlist::getInstance()->getNeutral())
66           continue;
67         Gtk::HBox *player_hbox = new Gtk::HBox();
68         Gtk::Image *image = new Gtk::Image();
69         image->property_pixbuf() = gc->getShieldPic(2, p)->to_pixbuf();
70         Gtk::ComboBoxText *type = new Gtk::ComboBoxText();
71         type->signal_changed().connect
72           (sigc::bind(sigc::mem_fun
73                       (this, &PreferencesDialog::on_type_changed), type));
74         Gtk::CheckButton *observe = new Gtk::CheckButton(_("Observe"));
75         observe->signal_toggled().connect
76           (sigc::bind(sigc::mem_fun
77                       (this, &PreferencesDialog::on_observe_toggled), observe));
78
79         observe->set_active(p->isObservable());
80         type->append_text(_("Human"));
81         type->append_text(_("Computer"));
82         if (p->getType() == Player::HUMAN)
83           {
84             observe->set_sensitive(false);
85             type->set_active(0);
86           }
87         else
88           type->set_active(1);
89         if (p->isDead() || (Playerlist::getActiveplayer() == p && 
90                             p->getType() != Player::HUMAN))
91           {
92             type->set_sensitive(false);
93             observe->set_sensitive(false);
94           }
95         if (readonly)
96           type->set_sensitive(false);
97         player_hbox->pack_start(*manage(image), Gtk::PACK_SHRINK, 
98                                 Gtk::PACK_SHRINK);
99         player_hbox->pack_start(*manage(type), Gtk::PACK_SHRINK, 10);
100         player_hbox->pack_start(*manage(observe), Gtk::PACK_SHRINK, 10);
101         //player_types.push_back(type);
102         player_types[p] = type;
103         player_observed[p] = observe;
104         //player_observed.push_back(observe);
105         Gtk::Label *player_name = new Gtk::Label(p->getName());
106         player_hbox->pack_start(*manage(player_name), Gtk::PACK_SHRINK, 10);
107         players_vbox->pack_start(*manage(player_hbox));
108       }
109     players_vbox->show_all_children();
110     commentator_checkbutton->signal_toggled().connect(
111         sigc::mem_fun(this, &PreferencesDialog::on_show_commentator_toggled));
112     speed_scale->set_value(Configuration::s_displaySpeedDelay);
113     speed_scale->signal_value_changed().connect(
114         sigc::mem_fun(this, &PreferencesDialog::on_speed_changed));
115     play_music_checkbutton->signal_toggled().connect(
116         sigc::mem_fun(this, &PreferencesDialog::on_play_music_toggled));
117     music_volume_scale->signal_value_changed().connect(
118         sigc::mem_fun(this, &PreferencesDialog::on_music_volume_changed));
119
120     commentator_checkbutton->set_active(Configuration::s_displayCommentator);
121     play_music_checkbutton->set_active(Configuration::s_musicenable);
122     music_volume_hbox->set_sensitive(Configuration::s_musicenable);
123     music_volume_scale->set_value(Configuration::s_musicvolume * 100.0 / 128);
124     
125 }
126
127 PreferencesDialog::~PreferencesDialog()
128 {
129   delete dialog;
130 }
131 void PreferencesDialog::set_parent_window(Gtk::Window &parent)
132 {
133     dialog->set_transient_for(parent);
134     //dialog->set_position(Gtk::WIN_POS_CENTER_ON_PARENT);
135 }
136
137 void PreferencesDialog::on_type_changed(Gtk::ComboBoxText *combo)
138 {
139   for (PlayerTypeMap::iterator it = player_types.begin();
140        it != player_types.end(); it++)
141     {
142       if (combo == (*it).second)
143         {
144           /**
145            * if we're turning this player into a human,
146            * then we desensitize the associated checkbutton
147            * otherwise, we presume that we want to observe it
148            */
149           if (combo->get_active_text() == _("Human"))
150             {
151               player_observed[(*it).first]->set_active(true);
152               player_observed[(*it).first]->set_sensitive(false);
153             }
154           else
155             {
156               player_observed[(*it).first]->set_sensitive(true);
157               player_observed[(*it).first]->set_active(true);
158             }
159         }
160     }
161 }
162
163 void PreferencesDialog::on_observe_toggled(Gtk::CheckButton *button)
164 {
165   for (PlayerObserveMap::iterator it = player_observed.begin();
166        it != player_observed.end(); it++)
167     {
168       if (button == (*it).second)
169         (*it).first->setObservable(button->get_active());
170     }
171 }
172
173 void PreferencesDialog::hide()
174 {
175   dialog->hide();
176 }
177
178 void PreferencesDialog::run(Game *game)
179 {
180     static int width = -1;
181     static int height = -1;
182
183     if (width != -1 && height != -1)
184         dialog->set_default_size(width, height);
185     
186     dialog->show();
187     dialog->run();
188     
189     dialog->get_size(width, height);
190     Configuration::saveConfigurationFile(Configuration::configuration_file_path);
191     PlayerTypeMap::iterator j = player_types.begin();
192     for (; j != player_types.end(); ++j)
193       {
194         Player *p = (*j).first;
195         if (p == NULL)
196           continue;
197         if (p == Playerlist::getInstance()->getNeutral())
198           continue;
199         if (p->getType() == Player::HUMAN) //changing human to:
200           {
201             if ((*j).second->get_active_text() == _("Human")) //human, no change
202               ;
203             else //computer, change to easy
204               {
205                 AI_Fast *new_player = new AI_Fast(*p);
206                 Player *old_player = p;
207                 Playerlist::getInstance()->swap(old_player, new_player);
208                 //disconnect and connect game signals
209                 game->addPlayer(new_player);
210                 delete old_player;
211               }
212           }
213         else //changing computer to:
214           {
215             if ((*j).second->get_active_text() == _("Human")) //human, change it
216               {
217                 RealPlayer *new_player = new RealPlayer(*p);
218                 Player *old_player = p;
219                 Playerlist::getInstance()->swap(old_player, new_player);
220                 //disconnect and connect game signals
221                 game->addPlayer(new_player);
222                 delete old_player;
223               }
224             else //computer, no change
225               ;
226           }
227       }
228     dialog->hide();
229 }
230
231 void PreferencesDialog::on_show_commentator_toggled()
232 {
233     Configuration::s_displayCommentator = commentator_checkbutton->get_active();
234 }
235
236 void PreferencesDialog::on_play_music_toggled()
237 {
238     bool play_music = play_music_checkbutton->get_active();
239
240     Configuration::s_musicenable = play_music;
241
242     if (play_music)
243     {
244         Sound::getInstance()->enableBackground();
245     }
246     else
247     {
248         Sound::getInstance()->haltMusic();
249         Sound::getInstance()->disableBackground();
250     }
251     music_volume_hbox->set_sensitive(Configuration::s_musicenable);
252 }
253
254 void PreferencesDialog::on_speed_changed()
255 {
256   Configuration::s_displaySpeedDelay = int(speed_scale->get_value());
257 }
258
259 void PreferencesDialog::on_music_volume_changed()
260 {
261     int volume = int(music_volume_scale->get_value() / 100 * 128);
262     
263 #ifdef FL_SOUND
264     Mix_VolumeMusic(volume);
265 #endif
266
267     Configuration::s_musicvolume = volume;
268 }
269