2 Copyright (C) 1999-2006 Id Software, Inc. and contributors.
3 For a list of contributors, see the accompanying CONTRIBUTORS file.
5 This file is part of GtkRadiant.
7 GtkRadiant is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 GtkRadiant 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.
17 You should have received a copy of the GNU General Public License
18 along with GtkRadiant; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 The following source code is licensed by Id Software and subject to the terms of
24 its LIMITED USE SOFTWARE LICENSE AGREEMENT, a copy of which is included with
25 GtkRadiant. If you did not receive a LIMITED USE SOFTWARE LICENSE AGREEMENT,
26 please contact Id Software immediately at info@idsoftware.com.
29 #if !defined( INCLUDED_PREFERENCES_H )
30 #define INCLUDED_PREFERENCES_H
32 #include "libxml/parser.h"
38 void Widget_connectToggleDependency(ui::Widget self, ui::Widget toggleButton);
40 class PreferencesPage {
44 PreferencesPage(Dialog &dialog, ui::VBox vbox) : m_dialog(dialog), m_vbox(vbox)
48 ui::CheckButton appendCheckBox(const char *name, const char *flag, bool &data)
50 return m_dialog.addCheckBox(m_vbox, name, flag, data);
53 ui::CheckButton appendCheckBox(const char *name, const char *flag, Property<bool> const &cb)
55 return m_dialog.addCheckBox(m_vbox, name, flag, cb);
58 void appendCombo(const char *name, StringArrayRange values, Property<int> const &cb)
60 m_dialog.addCombo(m_vbox, name, values, cb);
63 void appendCombo(const char *name, int &data, StringArrayRange values)
65 m_dialog.addCombo(m_vbox, name, data, values);
68 void appendSlider(const char *name, int &data, gboolean draw_value, const char *low, const char *high, double value,
69 double lower, double upper, double step_increment, double page_increment)
71 m_dialog.addSlider(m_vbox, name, data, draw_value, low, high, value, lower, upper, step_increment,
75 void appendRadio(const char *name, StringArrayRange names, Property<int> const &cb)
77 m_dialog.addRadio(m_vbox, name, names, cb);
80 void appendRadio(const char *name, int &data, StringArrayRange names)
82 m_dialog.addRadio(m_vbox, name, data, names);
85 void appendRadioIcons(const char *name, StringArrayRange icons, Property<int> const &cb)
87 m_dialog.addRadioIcons(m_vbox, name, icons, cb);
90 void appendRadioIcons(const char *name, int &data, StringArrayRange icons)
92 m_dialog.addRadioIcons(m_vbox, name, data, icons);
95 ui::Widget appendEntry(const char *name, Property<int> const &cb)
97 return m_dialog.addIntEntry(m_vbox, name, cb);
100 ui::Widget appendEntry(const char *name, int &data)
102 return m_dialog.addEntry(m_vbox, name, data);
105 ui::Widget appendEntry(const char *name, Property<std::size_t> const &cb)
107 return m_dialog.addSizeEntry(m_vbox, name, cb);
110 ui::Widget appendEntry(const char *name, std::size_t &data)
112 return m_dialog.addEntry(m_vbox, name, data);
115 ui::Widget appendEntry(const char *name, Property<float> const &cb)
117 return m_dialog.addFloatEntry(m_vbox, name, cb);
120 ui::Widget appendEntry(const char *name, float &data)
122 return m_dialog.addEntry(m_vbox, name, data);
125 ui::Widget appendPathEntry(const char *name, bool browse_directory, Property<const char *> const &cb)
127 return m_dialog.addPathEntry(m_vbox, name, browse_directory, cb);
130 ui::Widget appendPathEntry(const char *name, CopiedString &data, bool directory)
132 return m_dialog.addPathEntry(m_vbox, name, data, directory);
135 ui::SpinButton appendSpinner(const char *name, int &data, double value, double lower, double upper)
137 return m_dialog.addSpinner(m_vbox, name, data, value, lower, upper);
140 ui::SpinButton appendSpinner(const char *name, double value, double lower, double upper, Property<int> const &cb)
142 return m_dialog.addSpinner(m_vbox, name, value, lower, upper, cb);
145 ui::SpinButton appendSpinner(const char *name, double value, double lower, double upper, Property<float> const &cb)
147 return m_dialog.addSpinner(m_vbox, name, value, lower, upper, cb);
151 typedef Callback<void(PreferencesPage &)> PreferencesPageCallback;
153 class PreferenceGroup {
155 virtual PreferencesPage createPage(const char *treeName, const char *frameName) = 0;
158 typedef Callback<void(PreferenceGroup &)> PreferenceGroupCallback;
160 void PreferencesDialog_addInterfacePreferences(const PreferencesPageCallback &callback);
162 void PreferencesDialog_addInterfacePage(const PreferenceGroupCallback &callback);
164 void PreferencesDialog_addDisplayPreferences(const PreferencesPageCallback &callback);
166 void PreferencesDialog_addDisplayPage(const PreferenceGroupCallback &callback);
168 void PreferencesDialog_addSettingsPreferences(const PreferencesPageCallback &callback);
170 void PreferencesDialog_addSettingsPage(const PreferenceGroupCallback &callback);
172 void PreferencesDialog_restartRequired(const char *staticName);
174 template<typename Value>
179 const char *m_description;
181 LatchedValue(Value value, const char *description) : m_latched(value), m_description(description)
192 struct PropertyImpl<LatchedValue<T>, T> {
193 static void Export(const LatchedValue<T> &self, const Callback<void(T)> &returnz)
195 returnz(self.m_latched);
198 static void Import(LatchedValue<T> &self, T value)
200 self.m_latched = value;
201 if (value != self.m_value) {
202 PreferencesDialog_restartRequired(self.m_description);
208 Property<T> make_property(LatchedValue<T> &self)
210 return make_property<LatchedValue<T>, T>(self);
214 holds information for a given game
215 I'm a bit unclear on that still
216 it holds game specific configuration stuff
217 such as base names, engine names, some game specific features to activate in the various modules
218 it is not strictly a prefs thing since the user is not supposed to edit that (unless he is hacking
219 support for a new game)
221 what we do now is fully generate the information for this during the setup. We might want to
222 generate a piece that just says "the game pack is there", but put the rest of the config somwhere
223 else (i.e. not generated, copied over during setup .. for instance in the game tools directory)
225 class CGameDescription {
226 typedef std::map<CopiedString, CopiedString> GameDescription;
229 CopiedString mGameFile; ///< the .game file that describes this game
230 GameDescription m_gameDescription;
232 CopiedString mGameToolsPath; ///< the explicit path to the game-dependent modules
233 CopiedString mGameType; ///< the type of the engine
235 const char *getKeyValue(const char *key) const
237 GameDescription::const_iterator i = m_gameDescription.find(key);
238 if (i != m_gameDescription.end()) {
239 return (*i).second.c_str();
244 const char *getRequiredKeyValue(const char *key) const
246 GameDescription::const_iterator i = m_gameDescription.find(key);
247 if (i != m_gameDescription.end()) {
248 return (*i).second.c_str();
250 ERROR_MESSAGE("game attribute " << makeQuoted(key) << " not found in " << makeQuoted(mGameFile.c_str()));
254 CGameDescription(xmlDocPtr pDoc, const CopiedString &GameFile);
259 extern CGameDescription *g_pGameDescription;
263 class PreferencesPage;
265 class StringOutputStream;
268 standalone dialog for games selection, and more generally global settings
270 class CGameDialog : public Dialog {
273 mutable int m_nComboSelect; ///< intermediate int value for combo in dialog box
278 those settings are saved in the global prefs file
279 I'm too lazy to wrap behind protected access, not sure this needs to be public
280 NOTE: those are preference settings. if you change them it is likely that you would
281 have to restart the editor for them to take effect
285 what game has been selected
286 this is the name of the .game file
288 CopiedString m_sGameFile;
290 prompt which game to load on startup
294 log console to radiant.log
295 m_bForceLogConsole is an obscure forced latching situation
297 bool m_bForceLogConsole;
301 the list of game descriptions we scanned from the game/ dir
303 std::list<CGameDescription *> mGames;
308 m_bForceLogConsole(false)
312 virtual ~CGameDialog();
315 intialize the game dialog, called at CPrefsDlg::Init
316 will scan for games, load prefs, and do game selection dialog if needed
321 reset the global settings by removing the file
326 run the dialog UI for the list of games
332 this is only called when the dialog is built at startup for main engine select
334 ui::Window BuildDialog();
336 void GameFileImport(int value);
338 void GameFileExport(const Callback<void(int)> &importCallback) const;
341 construction of the dialog frame
342 this is the part to be re-used in prefs dialog
343 for the standalone dialog, we include this in a modal box
344 for prefs, we hook the frame in the main notebook
345 build the frame on-demand (only once)
347 void CreateGlobalFrame(PreferencesPage &page);
350 global preferences subsystem
351 XML-based this time, hopefully this will generalize to other prefs
352 LoadPrefs has hardcoded defaults
353 NOTE: it may not be strictly 'CGameDialog' to put the global prefs here
354 could have named the class differently I guess
357 void LoadPrefs(); ///< load from file into variables
358 void SavePrefs(); ///< save pref variables to file
363 scan for .game files, load them
368 inits g_Preferences.m_global_rc_path
370 void InitGlobalPrefPath();
373 uses m_nComboItem to find the right mGames
375 CGameDescription *GameDescriptionForComboItem();
379 this holds global level preferences
381 extern CGameDialog g_GamesDialog;
386 class PrefsDlg : public Dialog {
389 std::list<CGameDescription *> mGames;
393 ui::Widget m_notebook{ui::null};
397 g_string_free(m_rc_path, true);
398 g_string_free(m_inipath, true);
402 path for global settings
404 linux: ~/.radiant/[version]/
406 GString *m_global_rc_path;
409 path to per-game settings
410 used for various game dependant storage
412 linux: ~/.radiant/[version]/[gamename]/
417 holds per-game settings
418 m_rc_path+"local.pref"
419 \todo FIXME at some point this should become XML property bag code too
423 // initialize the above paths
426 /*! Utility function for swapping notebook pages for tree list selections */
427 void showPrefPage(ui::Widget prefpage);
432 ui::Window BuildDialog();
434 void PostModal(EMessageBoxReturn code);
437 extern PrefsDlg g_Preferences;
439 struct preferences_globals_t {
440 // disabled all INI / registry read write .. used when shutting down after registry cleanup
443 preferences_globals_t() : disable_ini(false)
448 extern preferences_globals_t g_preferences_globals;
450 void PreferencesDialog_constructWindow(ui::Window main_window);
452 void PreferencesDialog_destroyWindow();
454 void PreferencesDialog_showDialog();
456 void GlobalPreferences_Init();
458 void Preferences_Init();
460 void Preferences_Load();
462 void Preferences_Save();
464 void Preferences_Reset();